Reputation: 539
I try to insert a set of nodes from XML document into another one at a certain node. I followed the anser provided here
But I don't know why, all the attributes values are removed in the import.
Any idea ? Thansk a lot.
As requested here is a sample of XMLs I use:
XML1
<letterContent>
<key1>key1</key1>
<key2>key2</key2>
<type>456</type>
<object1>789</object1>
<effectiveDate>00</effectiveDate>
<expandedData attr1="case1">
<expandedData attr2="value2">
<data attrD="VD2">value D2</data>
</expandedData>
</expandedData attr3="value3">
<data attrD="vd3">value D3</data>
</expandedData>
</expandedData
</letterContent>
XML2
<expandedData attr4="value4">
<data attrd4="vd4">value d4</data>
<name nameattr="specific_name"/>
</expandedData>
The expected result:
<letterContent>
<key1>key1</key1>
<key2>key2</key2>
<type>456</type>
<object1>789</object1>
<effectiveDate>00</effectiveDate>
<expandedData attr1="case1">
<expandedData attr2="value2">
<data attrD="VD2">value D2</data>
</expandedData>
<expandedData attr3="value3">
<data attrD="vd3">value D3</data>
</expandedData>
<expandedData attr4="value4">
<data attrd4="vd4">value d4</data>
<name nameattr="specific_name"/>
</expandedData>
</expandedData
</letterContent>
As you can see there is a little difficulty because of nested element with similar name, but I can over pass this...
Here is the Java I use:
package org.test.XMLMERGE;
import static javax.xml.xpath.XPathConstants.*;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
public class Xml2into1 {
public static void main(String[] args) throws Exception {
// read from files
InputSource xml1 = new InputSource("R:/java/dev/tmp/dest.xml");
InputSource xml2 = new InputSource("R:/java/dev/tmp/orig2.xml");
// find the node to add to
XPath xpath = XPathFactory.newInstance()
.newXPath();
Node e1 = (Node) xpath.evaluate("//expandedData[@attr1='case1']", xml1, NODE);
Document doc1 = e1.getOwnerDocument();
// insert the nodes
Node e2 = (Node) xpath.evaluate("//expandedData[@attr4='value4']", xml2, NODE);
e1.appendChild(doc1.adoptNode(e2));
//.replaceChild(doc1.adoptNode(expandedData2), expandedData1);
// print results
TransformerFactory.newInstance()
.newTransformer()
.transform(new DOMSource(doc1), new StreamResult(System.out));
}
}
Finally here is the result I have:
<letterContent>
<key1>key1</key1>
<key2>key2</key2>
<type>456</type>
<object1>789</object1>
<effectiveDate>00</effectiveDate>
<expandedData attr1="case1">
<expandedData attr2="value2">
<data attrD="VD2">value D2</data>
</expandedData>
<expandedData attr3="value3">
<data attrD="vd3">value D3</data>
</expandedData>
<expandedData attr4="">
<data attrd4="">value d4</data>
<name nameattr=""/>
</expandedData>
</expandedData
</letterContent>
As you can see in the appended node all the attribute value are removed...
Upvotes: 2
Views: 4208
Reputation: 5552
According to Javadoc of org.w3c.dom.Document#adoptNode(Node)
:
ELEMENT_NODE
Specified attribute nodes of the source element are adopted. Default attributes are discarded, though if the document being adopted into defines default attributes for this element name, those are assigned. The descendants of the source element are recursively adopted.
By default, attributes are discarded—that's why node <expandedData>
is added without attributes. Use Document#importNode(Node importedNode, boolean deep)
with option deep=true
allows you to keep all attributes:
e1.appendChild(doc1.importNode(e2, true));
Result:
<letterContent>
...
<expandedData attr1="case1">
...
<expandedData attr4="value4">
<data attrd4="vd4">value d4</data>
<name nameattr="specific_name"/>
</expandedData>
</expandedData>
</letterContent>
Upvotes: 2