复制xml +添加根节点并删除中间的一些父节点

时间:2015-10-12 10:00:33

标签: xml xslt

正如马丁问的那样(Copy xml + remove some positional nodes),我为我的问题创建了一个新问题。

事情是这样的。我输入了上一个问题的输出。 问题是,我需要添加另一个Root节点。在xml中我需要删除OtherDoc节点。在目标中,他们只期望内部节点。

输入

<ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
   <ns0:childNode attribute1="test" attribute2="test">
      <levelA xmlns="http://schemas.microsoft.com/namespace2"/>
   </ns0:childNode>
   <ns0:childNode2 Name="childNode2">
      <levelA xmlns="http://schemas.microsoft.com/namespace3"/>
   </ns0:childNode2>
   <ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
      <ns0:levelA Name="levelA">
         <ns0:data Name="Data" id="123456" type="A"/>
         <ns0:data Name="Data" id="654321" type="B"/>
         <ns0:levelAA id="910038265">
            <ns0:repeatingItem id="910568755">
               <ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
                  <ns0:group Name="Group" id="12">
                     <ns0:doc xmlns:s7="http://Schemas.RepeatingItemMessageInformation" id="123" archived="0"/>
                     <ns0:doc xmlns:s7="http://Schemas.RepeatingItemMessageInformation" id="321" archived="0"/>
                  </ns0:group>
               </ns0:comm>
            </ns0:repeatingItem>
         </ns0:levelAA>
         <ns0:doc id="123">
            <ns0:externalDoc content="base64string"/>
         </ns0:doc>
         <ns0:doc id="321">
            <ns0:externalDoc content="base64string"/>
         </ns0:doc>
      </ns0:levelA>
   </ns0:ChildNode3>
</ns0:parentnode>

输出

<ns0:First xmlns:ns0="http://schemas.microsoft.com/namespace1">
    <ns0:parentnode xmlns:ns0="http://schemas.microsoft.com/namespace1" xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
       <ns0:childNode attribute1="test" attribute2="test">
          <levelA xmlns="http://schemas.microsoft.com/namespace2"/>
       </ns0:childNode>
       <ns0:childNode2 Name="childNode2">
          <levelA xmlns="http://schemas.microsoft.com/namespace3"/>
       </ns0:childNode2>
       <ns0:ChildNode3 Name="ChildNode3" id="2015-10-08-12.07.37.218960">
          <ns0:levelA Name="levelA">
             <ns0:data Name="Data" id="123456" type="A"/>
             <ns0:data Name="Data" id="654321" type="B"/>
             <ns0:levelAA id="910038265">
                <ns0:repeatingItem id="910568755">
                   <ns0:comm Name="Communication" id="910041726" numberOfDocuments="3">
                      <ns0:group Name="Group" id="12">
                         <ns0:doc xmlns:s7="http://Schemas.RepeatingItemMessageInformation" id="123" archived="0"/>
                         <ns0:doc xmlns:s7="http://Schemas.RepeatingItemMessageInformation" id="321" archived="0"/>
                      </ns0:group>
                   </ns0:comm>
                </ns0:repeatingItem>
             </ns0:levelAA>
             <ns0:externalDoc content="base64string"/>
             <ns0:externalDoc content="base64string"/>
          </ns0:levelA>
       </ns0:ChildNode3>
    </ns0:parentnode>
</ns0:First>

因此添加rootnamespace不是问题。我也可以更改名称空间。因为还有来源和目标命名空间不同。 我唯一需要的是删除了OtherDoc。不失去复制完整消息的功能。因为它们比这个例子xml

更多

XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
                exclude-result-prefixes="msxsl var s0 " version="1.0"
                xmlns:ns0="http://schemas.microsoft.com/namespace1"
                xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
                xmlns:s7="http://Schemas.RepeatingItemMessageInformation"
                xmlns:ns1="http://schemas.microsoft.com/namespace2">

<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes">     

<xsl:template match="/">
    <xsl:apply-templates select="/ns0:parentnode" />
  </xsl:template>
  <xsl:template match="/ns0:parentnode">
    <ns1:First>
      <ns1:parentnode>
        <xsl:for-each select="ns0:ChildNode3">
        <ns1:ChildNode3>
            <xsl:copy-of select="./@*" />
            <xsl:apply-templates select="./*" />
        </ns1:ChildNode3>
        </xsl:for-each>
      </ns1:parentnode>
    </ns0:First>
  </xsl:template>

  <xsl:template match="ns0:*">
    <xsl:element name="ns1:{local-name()}">
      <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy-of select="."/>
  </xsl:template>  

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

如果要删除doc节点,但仍然输出子节点(在不同的命名空间中),则只需添加另一个模板即可明确匹配doc,这将继续通过处理它的子节点,但不输出节点本身。

将此模板添加到XSLT

 <xsl:template match="ns0:doc[ns0:externalDoc]">
     <xsl:apply-templates select="node()"/>
 </xsl:template>

这只会将doc元素与子externalDoc匹配。

或者,您只能匹配doc元素中的LevelA个元素。你也可以试试这个,在这种情况下:

 <xsl:template match="ns0:levelA/ns0:doc">
     <xsl:apply-templates select="node()"/>
 </xsl:template>