【问题标题】:XML Merging using XPATH使用 XPATH 进行 XML 合并
【发布时间】:2017-01-11 05:06:57
【问题描述】:

我正在尝试使用合并两个 xml “javax.xml.xpath.XPath”。

源 xml 和目标 xml 如下所述。 我想将第二个xml中“bpmn:process”的所有节点追加到第一个xml

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
  <bpmn:collaboration id="Collaboration_1ah989h">
    <bpmn:participant id="Participant_108if28" processRef="Process_2" />
   </bpmn:collaboration>

  <bpmn:process id="Process_1" isExecutable="false">**
   <bpmn:startEvent id="StartEvent_1">
     <bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>
   </bpmn:startEvent>
   <bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
  <bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
   <bpmn:outgoing>SequenceFlow_05qx4z2</bpmn:outgoing>
  </bpmn:intermediateThrowEvent>
   </bpmn:process>

 </bpmn:definitions>

下面是用于合并xml的代码

Document destination= (Document) xpath.evaluate("/", new InputSource("C:/diagram_Sec.bpmn"),   XPathConstants.NODE);

NodeList listPosts = (NodeList) xpath.evaluate("//bpmn:process//*",new InputSource("C:/diagram_Fir.xml"), XPathConstants.NODESET);

 Element element= (Element) xpath.evaluate("//bpmn:process", destination,    XPathConstants.NODE);

 for (int i = 0; i < listPosts.getLength(); i++) {

    Node listPost = listPosts.item(i);
    Element element = (Element) listPost;

   AttributeMap map =   (AttributeMap) element.getAttributes();
   for(int j=0;j<map.getLength();j++)
    {
     element.setAttribute(map.item(j).getLocalName(), map.item(j).getNodeValue());

    }
       Node node = xml1.adoptNode(element);
       blog.appendChild(node);

 }

   DOMImplementationLS impl = (DOMImplementationLS) xml1.getImplementation();
  System.out.println(impl.createLSSerializer().writeToString(destination ));

问题是,这段代码会将“bpmn:process”标签的所有子节点视为单独的节点,并将直接放在“bpmn:process”下(所有子子节点也会放在“bpmn:process”下) .输出看起来像这样

<bpmn:process id="Process_1" isExecutable="false">
 //Here comes First xml nodes

  //Second XML Content after merge
 <bpmn:startEvent id="StartEvent_1">
 </bpmn:startEvent>

 **//This tag should be inside bpmn:startEvent  tag**
<bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>

<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
 </bpmn:intermediateThrowEvent> 

 **//THis should be inside above bpmn:intermediateThrowEvent  tag**
<bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
</bpmn:process

但预期是

    <bpmn:process id="Process_1" isExecutable="false">
 //Here comes First xml Children

  //Second XML Content
 <bpmn:startEvent id="StartEvent_1">
   // outgoing is Inside bpmn:startEvent  tag
 **<bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>**
 </bpmn:startEvent>

<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
 // Inside bpmn:intermediateThrowEvent tag
<bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
 </bpmn:intermediateThrowEvent> 

</bpmn:process

请告诉我正确的做法。

谢谢,

【问题讨论】:

  • 你能同时显示你的xml而不是一个吗?

标签: java xml xpath merge xml-parsing


【解决方案1】:

XPath 是一种只读语言:您不能使用它来构造新的 XML 树。为此,您需要 XSLT 或 XQuery。或者 DOM,如果你真的想沉到那么低。

但这在 XSLT 中是如此简单,以至于使用 DOM 似乎真的是浪费精力。在 XSLT 中,您只需要两个模板规则:复制所有内容不变的标准身份规则,以及规则

<xsl:template match="bpmn:process">
  <xsl:copy-of select="."/>
  <xsl:copy-of select="document('second.xml')//bpmn:process"/>
</xsl:template>

【讨论】:

  • 您好 Michael,感谢您的建议,我将尝试使用 XSLT。
猜你喜欢
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2013-09-06
相关资源
最近更新 更多