这种转换似乎是当前发布的解决方案中最有效的——否count(preceding-sibling::*)
和否//content[@key=$key]
——两者都导致 O(N^2)——二次时间复杂度:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kContByAtttr" match="content" use="@key"/>
<xsl:key name="kVidByAtttr" match="video" use="@key"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="contents">
<contents>
<xsl:for-each select="/*/videos/video">
<xsl:apply-templates select="key('kContByAtttr', @key)"/>
</xsl:for-each>
<xsl:apply-templates select="*[not(key('kVidByAtttr', @key))]"/>
</contents>
</xsl:template>
</xsl:stylesheet>
当应用于提供的 XML(包装到单个顶部元素中以成为一个)文档时:
<t>
<videos>
<video key="13" />
<video key="41" />
<video key="61" />
</videos>
<contents>
<content key="61" />
<content key="41" />
<content key="13" />
<content key="10" />
</contents>
</t>
产生想要的正确结果:
<t>
<videos>
<video key="13"/>
<video key="41"/>
<video key="61"/>
</videos>
<contents>
<content key="13"/>
<content key="41"/>
<content key="61"/>
<content key="10"/>
</contents>
</t>