我有以下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="Baz"/>
<parent name="Qux"/>
</thing>
</things>
这表示如下结构:
实际的XML非常大,嵌套很深。无法实现的东西可以在任何地方。没有循环(自己作为祖先的东西)。
现在我想生成所有可能的Waldo路径,过滤掉包含不可用内容的路径。我正在寻找以下结果:
<ul>
<li>
<a href="#Foo">Foo</a>
<ul>
<li>
<a href="#Baz">Baz</a>
<ul>
<li>
<b>Waldo</b>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<a href="#Foo">Foo</a>
<ul>
<li>
<b>Waldo</b>
</li>
</ul>
</li>
</ul>
那是:
从叶子节点开始,查找树,生成所有可能的路径而忽略不可用的路径让我感到难过。任何见解,散文,伪代码或XSLT都非常感谢!
答案 0 :(得分:1)
此转化:
<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格式的练习。
<强>解释强>:
这是两次转换。
第一遍构造了一个树,其中明确表达了父子关系。
第二遍是一个身份规则,由一个带有空体(“删除”模板)的模板覆盖,用于不包含属性为thing
的{{1}}的子树,带有字符串 - 价值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>
元素以产生最终结果。