2

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...

0

1 Answer 1

2

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much. It works perfectly. BTW, thanks for w3c link: This was the entry point to find the solution.
@Zamboo you're welcome. It's my pleasure to be able to help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.