这种转变:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kChildren" match="thing" use="parent/@name"/>
<xsl:template match="/*">
<xsl:variable name="vrtfPass1">
<things>
<xsl:apply-templates select="thing[not(parent)]"/>
</things>
</xsl:variable>
<xsl:apply-templates select="ext:node-set($vrtfPass1)/*"
mode="pass2"/>
</xsl:template>
<xsl:template match="thing">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('kChildren', @name)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template mode="pass2"
match="*[not(@name = 'Waldo' or .//*[@name='Waldo'])]" />
</xsl:stylesheet>
应用于提供的 XML 文档时:
<things>
<thing name="Foo" available="yes"/>
<thing name="Bar" available="no"/>
<thing name="Baz" available="yes">
<parent name="Foo"/>
<parent name="Bar"/>
</thing>
<thing name="Qux" available="no">
<parent name="Foo"/>
<parent name="Bar"/>
</thing>
<thing name="Waldo" available="yes">
<parent name="Foo"/>
<parent name="Bar"/>
<parent name="Qux"/>
</thing>
</things>
产生一个只包含包含“waldo”的“分支”的结果:
<things>
<thing name="Foo" available="yes">
<thing name="Qux" available="no">
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Bar" available="no">
<thing name="Qux" available="no">
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Waldo" available="yes"/>
</thing>
</things>
将其转换为所需的最终 HTML 格式留给读者作为练习。
说明:
这是一个两遍转换。
第一遍构造一棵树,其中明确表达了父子关系。
第二遍是一个身份规则,由一个带有空主体的模板(“删除”模板)覆盖,用于不包含带有 string-value的thing
with 属性的子树。name
"Waldo"
第一遍的结果是:
<things>
<thing name="Foo" available="yes">
<thing name="Baz" available="yes"/>
<thing name="Qux" available="no">
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Bar" available="no">
<thing name="Baz" available="yes"/>
<thing name="Qux" available="no">
<thing name="Waldo" available="yes"/>
</thing>
<thing name="Waldo" available="yes"/>
</thing>
</things>
第二遍去除两个<thing name="Baz" available="yes"/>
元素以产生最终结果。