How to insert XmlCursor content to DOM Document - java

Some API returns me XmlCursor pointing on root of XML Document. I need to insert all of this into another org.w3c.DOM represented document.
At start:
XmlCursor poiting on
<a>
<b>
some text
</b>
</a>
DOM Document:
<foo>
</foo>
At the end I want to have original DOM document changed like this:
<foo>
<someOtherInsertedElement>
<a>
<b>
some text
</b>
</a>
</someOtherInsertedElement>
</foo>
NOTE: document.importNode(cursor.getDomNode()) doesn't work - Exception is thrown: NOT_SUPPORTED_ERR: The implementation does not support the requested type of object or operation.

Try something like this:
Node originalNode = cursor.getDomNode();
Node importNode = document.importNode(originalNode.getFirstChild());
Node otherNode = document.createElement("someOtherInsertedElement");
otherNode.appendChild(importNode);
document.appendChild(otherNode);
So in other words:
Get the DOM Node from the cursor. In this case, it's a DOMDocument, so do getFirstChild() to get the root node.
Import it into the DOMDocument.
Do other stuff with the DOMDocument.
Append the imported node to the right Node.
The reason to import is that a node always "belongs" to a given DOMDocument. Just adding the original node would cause exceptions.

I was having the same issue.
This was failing:
Node importNode = document.importNode(originalNode);
This fixed the problem:
Node importNode = document.importNode(originalNode.getFirstChild());

Related

Select all nodes of a type under a given node

i'm new to XNode and want to select all nodes of a type under a given node. In the following example, i'm looking for all bar nodes beneath the foo node.
<node>
<foo>
<bar/>
<div><bar/></div>
<ul>
<li><bar/>
</ul>
<p>foobar</p>
</foo>
<bar/>
</node>
My Application gets the foo node (org.w3c.dom.Node):
NodeList nodeList = (NodeList) xpath.evaluate("//bar", fooNode, XPathConstants.NODESET);
Returns all bar nodes of the whole document, not from the fooNode even though i passed the node and not the whole document.
Returns all bar nodes of the whole document, not from the fooNode even
though i passed the node and not the whole document.
That's the expected behavior for an absolute location path as //bar. Use a relative location path as .//bar or descendant-or-self::bar or descendant::bar
I'm not sure this is what you're looking for, but
//foo/descendant-or-self::bar
selects the 3 </bar>s inside <foo>.

Why is DOM doing this? (Wrong nodeName XML)

I have this XML (just a little part.. the complete xml is big)
<Root>
<Products>
<Product ID="307488">
<ClassificationReference ClassificationID="AR" Type="AgencyLink"/>
<ClassificationReference ClassificationID="AM" Type="AgencyLink">
<MetaData>
<Value AttributeID="tipoDeCompra" ID="C">Compra Centralizada</Value>
</MetaData>
</ClassificationReference>
</Product>
</Products>
</Root>
Well... I want to get the data from the line
<Value AttributeID="tipoDeCompra" ID="C">Compra Centralizada</Value>
I'm using DOM and when I use nodoValue.getTextContent() I got "Compra Centralizada" and that is ok...
But when I use nodoValue.getNodeName() I got "MetaData" but I was expecting "Value"
What is the explanations for this behaviour?
Thanks!
Your nodeValuevariable most likely points to the MetaData node, so the returned name is correct.
Note that for an element node Node.getTextContent() returns the concatenation of the text content of all child nodes. Therefore in your example the text content of the MetaData element is equal to the text content of the Value element, namely Compra Centralizada.
I guess your are getting the Node object using getElementsByTagName("MetaData"). In this case nodoValue.getTextContent() will return the text content correctly but to get the node name you need to get the child node.
Your current node must be MetaData and getTextContent() will give all the text within its opening and closing tags. This is because you are getting
Compra Centralizada
as the value. You should get the first child using getChildNodes() and then can get the Value tag.

Does org.dom4j.io.SAXReader.read(Reader reader) method preserves the order of elements and attributes of XML

My XML file is:
<XYZ>
<A name="one">
<label>I am A one</label>
</A>
<B name="two">
<label>I am B two</label>
</B>
<A name="three">
<label>I am A three</label>
</A>
</XYZ>
My Code is:
String myXmlAsString = //Read the above xml as String
Document document = new SAXReader().read(new StringReader(myXmlAsString ));
List<Element> dataElements = document.selectNodes("/XYZ");
My Question is:
If I read my XML file through above mentioned code then does the dataElements List returned by selectNodes(String xPathExpr) method will have the same order as in the original XML file?
If yes, does this holds true even if the XML has deep nesting and I call the selectNodes(String xPathExpr) method on any Element object from this document object.
XPath does not change the order of elements when returning results, so the elements are exactly in the same order as in your input xml.
Lists are ordered structures. There is no reason for the SAXReader to remove that order.

Replacing xml node from another xml

i use Java and I have 2 xml files like
<xml>
<a value="5">
<b value="7">
<c>
<d value="9">
</c>
<xml>
and
<xml>
<c>
<d value="8">
</c>
<xml>
So what i want is for every node in second xml if there exists with same node path in first xml, replace the first xml's node with the second xml's node.For these xmls, i expect
<xml>
<a value="5">
<b value="7">
<c>
<d value="8">
</c>
<xml>
Many Thanks for Your Help
You can use a Sax parser and iterate through second XML and get all the available nodes. Or use DOM for that. Same way get all nodes in first XML. Then write a logic to find the matching nodes. Then use DOM to edit first XML. Try it your self so that you can learn. See how to edit XML here
there man ways to read xml and write xml like DOM parser , jaxB so i would prefer to use JAXB marshall and unmarshaller so that you can have an object of your xml file and to set the value and get the value becomes easier

How to remove CDATA from XML in Java and do some conversion?

I am trying create Java Servlet which will modify existing XML.
This a part of my orginal XML:
<customfieldvalues>
<div id="errorDiv" style="display:none;"/>
<![CDATA[
Vinduer, dører
]]>
</customfieldvalues>
I want to get the following result:
<customfieldvalues>
<div id="errorDiv" style="display:none;"/>
Vinduer, dører
</customfieldvalues>
I iterate over the XML structure with:
Document doc = parseXML(connection.getInputStream());
NodeList descNodes = doc.getElementsByTagName("customfieldvalues");
for (int i=0; i<descNodes.getLength();i++) {
Node node = descNodes.item(i);
// how to ?
}
So, I need to remove CDATA and convert the content.
I saw that I can use this for the conversion.
javax.xml.parsers.DocumentBuilderFactory.setCoalescing API
Specifies that the parser produced by this code will
convert CDATA nodes to Text nodes and append it to the
adjacent (if any) text node. By default the value of this is set to
false

Categories