how to update xml using xPath - java

i have the following xml file:
<?xml version='1.0' encoding='utf-8' ?>
<osm>
<node id="25779111" lat="50.03342" lon="5.461545"/>
<node id="25779112" lat="50.03304" lon="5.814"/>
<node id="25779119" lat="50.03395" lon="5.8255"/>
<tag k="maxspeed" v="30"/>
<tag k="maxspeed:zone" v="yes"/>
<ele k="maxspeed:zone" v="60"/>
and i reviewed some posts to know how can i update or change a value in the xml file using xpath, and idid the following :
for (int i = 1 ; i <= 2; i++) {
String expr0 = "//node[#lat='53.0334062'][#lon='8.8461545']/following-sibling::tag["+i+"]/#v";
xPath.compile(expr0);
Node s = (Node) xPath.evaluate(expr0, document, XPathConstants.NODE);
System.out.println(s);
s.setNodeValue("999");
}
but when i checked the xml file, i expected to see the change written to it, but there was no change.
please let me know how to change the value in the xml file using xPath correctly.

you need to write the document back to the disk. Here's how:
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
String filePath = "path/to/new/file.xml";
StreamResult streamResult = new StreamResult(new File(filePath));
transformer.transform(source, streamResult);
More help here: http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT4.html
Hope this helps. :)

Related

Pre-added Whitespaces in XML on first line only

I am facing an issue while generating XML through Java code. I am printing the xml directly onto webpage to present the stats. The first line of the generated XML is always having some spaces at the start which makes the XML look weird. How do I remove the same. I tried removing the xml line but still whatever be the first line it has pre white spaces.
Please let me now how do i remove it
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<headNode>
<statsHead1>
<totalCount>0.05</totalCount>
</statsHead1>
<statsHead2>
<statsSubHead1>
<count1>0</count1>
<count2>0.0</count2>
</statsSubHead1>
<statsSubHead2>
<count1>0</count1>
<count2>0.0</count2>
</statsSubHead2>
<totalcount1>0</totalcount1>
<totalcount2>0.0</totalcount2>
</statsHead2>
</headNode>
Code that I use is
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StringWriter outWriter = new StringWriter();
Result result = new StreamResult(outWriter);
transformer.transform(source, result);
return outWriter.toString();

DOM XML Public Doctype not appearing in result xml file

I have written a code to generate XML files. I am stuck at defining doctype for the XML as it should be public. I am able to get SYSTEM doctype successfully but somehow not able to get public doctype written in XML. Below code for SYSTEM doctype is working but same snippet for PUBLIC doctype is not working :
String xmldestpath = "C:/failed/tester.xml";
doctype2 = CreateDoctypeString();
StreamResult result = new StreamResult(new File(xmldestpath ));
try {
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,"TEST");
transformer.transform(source, result);
// logger.debug("COMPLETED Copying xml files /....!!");
System.out.println("COMPLETED Copying xml files to bulk import....!!");
Not working snippet. Its not giving error but no doctype is appearing in resultant xml:
String xmldestpath = "C:/failed/tester.xml";
doctype2 = CreateDoctypeString();
StreamResult result = new StreamResult(new File(xmldestpath ));
try {
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"TEST");
transformer.transform(source, result);
// //logger.debug("COMPLETED Copying xml files /....!!");
System.out.println("COMPLETED Copying xml files to bulk import....!!");
If you know you need/want PUBLIC, perhaps you should know that a public literal cannot exist without a system literal.
The XML specification shows:
ExternalID ::= 'SYSTEM' S SystemLiteral
| 'PUBLIC' S PubidLiteral S SystemLiteral
So it should be easy to conclude that you need to specify both in order to get it to work, as demonstrated by this MCVE:
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "TEST1");
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "TEST2");
transformer.transform(new StreamSource(new StringReader("<Root></Root>")),
new StreamResult(System.out));
Output
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Root PUBLIC "TEST1" "TEST2">
<Root/>

how to print double quotes in xml attribute value

Hi i am generating a xml file using javax.xml parsers able to generate a xml file. But in my attribute value i was getting &quot instead of double quote.
How to print double quotes in attribute value. Below is my code
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("elements");
doc.appendChild(rootElement);
rootElement.setAttribute("area", "area");
rootElement.setAttribute("page", "pagename");
//element
Element element = doc.createElement("element");
rootElement.appendChild(element);
element.setAttribute("key", "key");
element.setAttribute("id", "id");
element.setAttribute("path", "//*[#id="email"]");
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(ApplicationContext.getPath()+File.separator+"test.xml"));
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
Output :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<elements area="area" page="pagename">
<element id="id" key="key" path="//*[#id="email"]"/>
</elements>
Expected output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<elements area="area" page="pagename">
<element id="id" key="key" path="//*[#id="email"]"/>
</elements>
Thanks inadvance
The output you are trying to produce is not well-formed XML, and no XML parser will accept it. If you want to produce stuff that isn't XML then you can do so, of course, but XML-aware tools will try very hard to prevent it.

Java creates additional element under root element

So I have an XML file that looks like the following:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE config SYSTEM "config.dtd">
<config>
<domains>
</domains>
</config>
I need to create a new element called session with two attributes let's call this atrib 1 and atrib 2.
So ultimately I would like the XML file to look like this.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE config SYSTEM "config.dtd">
<config>
<session atrib1="100" artib2="200" />
<domains>
</domains>
</config>
I've been playing around with the document builder but cannot seem to figure out how to get this to work.
Below is the modified version from the tips below. The new element is not being created and the & is being removed from the xml file.
File file = new File(fileLocaton);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
document = docBuilder().parse(file);
Element rootElement = document.getDocumentElement();
Element sSession = document.createElement("session");
// set attributes
sSession.setAttribute("attr1", "100");
sSession.setAttribute("attr2", "200");
// instead of appending, insert in front of the first child
rootElement.insertBefore(sSession, rootElement.getFirstChild());
DOMSource source = new DOMSource(document);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult(file.getPath());
transformer.transform(source, result);

Output format of XML empty element in Java

I wrote code below to get XML output.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element element = document.createElement("Test");
Text text = document.createTextNode("");
element.appendChild(text);
document.appendChild(element);
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
What I got is
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Test/>
What I want to get is
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Test></Test>
How can I do this?
Many thanks.
There is no clean way to do this..
If you feel comfortable to use duct-tape solutions, you could let your transformer output html instead of xml:
transformer.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html");
But again, I have to point out that this is not a clean solution, but it did the trick for me as I was stuck with a similar problem

Categories