Xml xslt解析层次结构并复制到新文档中

Xml xslt解析层次结构并复制到新文档中,xml,xslt,xslt-2.0,Xml,Xslt,Xslt 2.0,我有这样一个xml文档: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <nodes> <node id="123"> <elemref id="1"/> <elemref id="2"/> <noderef id="222"/> </node> <node id="456"> <elemref id="4

我有这样一个xml文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<nodes>
<node id="123">
   <elemref id="1"/>
   <elemref id="2"/>
   <noderef id="222"/>
</node>
<node id="456">
   <elemref id="4">
      <elemref id="2828"/>
   </elemref>
   <elemref id="5"/>
   <noderef id="444"/>
</node>
<node id="222">
   <elemref id="6"/>
   <elemref id="8"/>
   <noderef id="666"/>
</node>
<node id="444">
   <elemref id="11"/>
   <elemref id="22"/>
   <noderef id="888"/>
</node>
</nodes>
预期产出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<nodes>
<node id="123">
   <elemref id="1"/>
   <elemref id="2"/>
   <subnode id="222">
       <elemref id="6"/>
       <elemref id="8"/>
   <!-- resolve noderef 666 -->
   </subnode>  
</node>
<node id="456">
   <elemref id="4">
      <elemref id="2828"/>
   </elemref>
   <elemref id="5"/>
   <subnode id="444">
       <elemref id="11"/>
       <elemref id="22"/>
       <!-- resolve noderef 888 -->
   </subnode>
</node>
</nodes>
所以基本上我需要解决所有的问题。它们所指的节点位于同一文档中,此处为方便起见,将节点666和888写入其中。我需要一个正确显示节点和元素层次结构的文档。任何东西都可以嵌套任意深度

因此,每个节点都可能有未知数量的elemref,每个elemref和noderef都可能包含可变数量的elemref,而noderef又反过来包含elemref等等


我将非常感谢任何提示和帮助!使用XSLT 2.0

如果我正确理解这一点,使用以下工具应该非常容易:

XSLT


希望您没有任何循环引用。

如果我理解正确,使用以下方法应该很容易:

XSLT


希望您没有任何循环引用。

它似乎起了作用:D非常感谢您没有时间解释它是如何工作的?第一个模板按原样复制所有内容,第二个模板选择不具有相同id的noderef元素的所有节点,最后一个模板选择所有noderef并将其替换为,然后按原样选择所有子节点?钥匙到底返回了什么,这样你就可以不用钥匙了?我真的不明白copy元素是如何工作的。为什么要使用复制然后在内部应用模板?如果它有循环引用,会有什么不同?这会不会行不通。xsl copy做了一个浅层复制:它复制元素,但不复制其内容。-2.key函数返回一组与键值匹配的节点;谓词[notkey…]仅选择没有与键值匹配的对应节点的节点。-3.一个循环引用会把你的处理器送入一个无限循环。它似乎已经工作了:D非常感谢你你没有时间解释它是如何工作的?第一个模板按原样复制所有内容,第二个模板选择不具有相同id的noderef元素的所有节点,最后一个模板选择所有noderef并将其替换为,然后按原样选择所有子节点?钥匙到底返回了什么,这样你就可以不用钥匙了?我真的不明白copy元素是如何工作的。为什么要使用复制然后在内部应用模板?如果它有循环引用,会有什么不同?这会不会行不通。xsl copy做了一个浅层复制:它复制元素,但不复制其内容。-2.key函数返回一组与键值匹配的节点;谓词[notkey…]仅选择没有与键值匹配的对应节点的节点。-3.循环引用将使处理器进入无限循环。
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="node-by-id" match="node" use="@id" />
<xsl:key name="noderef-by-id" match="noderef" use="@id" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- only unreferenced nodes are ancestors -->
<xsl:template match="/nodes">
    <xsl:copy>
        <xsl:apply-templates select="node[not(key('noderef-by-id', @id))]"/>
    </xsl:copy>
</xsl:template>

<!-- resolve references -->
<xsl:template match="noderef">
    <subnode id="{@id}">
       <xsl:apply-templates select="key('node-by-id', @id)/*"/>
   </subnode>  
</xsl:template>

</xsl:stylesheet>