XPATH:将xml节点插入另一个XML文档

时间:2018-06-01 11:26:45

标签: java xml xpath

我尝试将XML文档中的一组节点插入到某个节点的另一个节点中。 我跟着提供here

的anser

但我不知道为什么,导入时会删除所有属性值。

有什么想法吗? Thansk很多。

这里要求的是我使用的XML样本:

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>

预期结果:

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

正如您所看到的那样,由于具有相似名称的嵌套元素存在一些困难,但我可以通过这个......

这是我使用的Java:

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));
  }
}

最后,这是我的结果:

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

正如您在附加节点中看到的那样,所有属性值都被移除......

1 个答案:

答案 0 :(得分:1)

根据org.w3c.dom.Document#adoptNode(Node)的Javadoc:

  

ELEMENT_NODE

     

采用源元素的指定属性节点。默认属性将被丢弃,但如果采用的文档定义了此元素名称的默认属性,则会分配这些属性。源元素的后代是递归采用的。

默认情况下,属性被丢弃 - 这就是添加节点<expandedData>而没有属性的原因。使用Document#importNode(Node importedNode, boolean deep)选项deep=true可以保留所有属性:

e1.appendChild(doc1.importNode(e2, true));

结果:

<letterContent>
  ...
  <expandedData attr1="case1">
    ...
    <expandedData attr4="value4">
      <data attrd4="vd4">value d4</data>
      <name nameattr="specific_name"/>
    </expandedData>
  </expandedData>
</letterContent>