xslt 解析层次结构并复制到新文档中
xslt resolve hierarchy and copy into new document
我有一个这样的 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)。我需要一个正确显示节点和 elemrefs 层次结构的文档。一切都可以嵌套任意深度。
因此每个节点可以有未知数量的 elemrefs,每个 elemrefs 可以包含可变数量的 elemrefs 和 noderefs,后者又包含 elemrefs 等等。
如果有任何提示和帮助,我将不胜感激!使用 XSLT 2.0
如果我理解正确的话,使用 keys:
应该很容易做到
XSLT
<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>
希望您没有任何循环引用。
我有一个这样的 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)。我需要一个正确显示节点和 elemrefs 层次结构的文档。一切都可以嵌套任意深度。
因此每个节点可以有未知数量的 elemrefs,每个 elemrefs 可以包含可变数量的 elemrefs 和 noderefs,后者又包含 elemrefs 等等。
如果有任何提示和帮助,我将不胜感激!使用 XSLT 2.0
如果我理解正确的话,使用 keys:
应该很容易做到XSLT
<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>
希望您没有任何循环引用。