我想对以下XML文件进行排序:
<root>
<element name="a" depends="b,c" />
<element name="b" depends="c" />
<element name="c" />
</root>
结果如下:
<root>
<element name="c" />
<element name="b" depends="c" />
<element name="a" depends="b,c" />
</root>
我的依赖关系可以使用树(无循环)建模。 depends =“b,c”表示取决于b和c。 我想通过使用XSLT来做到这一点的好方法。也许,你有什么想法吗? 谢谢!
答案 0 :(得分:1)
此XSLT 2.0转换:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<root>
<xsl:call-template name="directDependents"/>
</root>
</xsl:template>
<xsl:template name="directDependents">
<xsl:param name="pCore" as="element()*"/>
<xsl:variable name="vNewDependents" select=
"/*/element
[not(. intersect $pCore)
and
not(tokenize(@depends, ',')[not(. = $pCore/@name)])
]
"/>
<xsl:if test="$vNewDependents">
<xsl:sequence select="$vNewDependents"/>
<xsl:call-template name="directDependents">
<xsl:with-param name="pCore" select="$pCore | $vNewDependents"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于(第二个)提供的XML文档:
<root>
<element name="a" depends="b" />
<element name="b" depends="c" />
<element name="c" />
</root>
生成想要的正确结果:
<root>
<element name="c"/>
<element name="b" depends="c"/>
<element name="a" depends="b"/>
</root>
更新:这是一个更“XSLT 2.0外观解决方案”(未经测试 - 将在我回家时纠正任何错误):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<root>
<xsl:sequence select="my:directDependents(/..)"/>
</root>
</xsl:template>
<xsl:function name="my:directDependents">
<xsl:param name="pCore" as="element()*"/>
<xsl:sequence select=
"for $vNewDependents in
/*/element
[not(. intersect $pCore)
and
not(tokenize(@depends, ',')[not(. = $pCore/@name)])
]
return
if($vNewDependents)
then
(
$vNewDependents,
my:directDependents($pCore | $vNewDependents)
)
else ()
"/>
</xsl:function>
</xsl:stylesheet>