Zamboo
Zamboo

Reputation: 539

XPATH: Insert xml nodes into another XML document

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

Answers (1)

Mincong Huang
Mincong Huang

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

Related Questions