基于输出树的XSLT条件
我习惯于在XSLT中使用基于输入中节点树的条件。但是我想根据输出来做。有办法吗 这里有一个例子 输入:基于输出树的XSLT条件,xslt,tree,Xslt,Tree,我习惯于在XSLT中使用基于输入中节点树的条件。但是我想根据输出来做。有办法吗 这里有一个例子 输入: <top> <a> <z> <item> <id>4</id> </item> <item> <id>5</id>
<top>
<a>
<z>
<item>
<id>4</id>
</item>
<item>
<id>5</id>
</item>
</z>
</a>
</top>
这是一个简化的示例,在a和z之间的树中有许多节点,项目节点可以显示在a下的不同深度
起初,我从一个类似于祖先::upper的条件开始,但显然这不起作用,因为upper在输出中,而不是在输入中
我还考虑过尝试传递一个参数来表示我们是处于上限还是下限,但这意味着更新每个模板,包括标识模板,使其具有参数,并将其传递给它调用的任何模板。如果可能的话,我真的想避免这种情况
因此,如果有一种方法可以在不声明变量的情况下将变量传递给被调用的模板,那就行了。或者,如果我可以编写一个条件来查看调用我们的模板或我们上面树中的输出,那就行了。或者还有其他方法可以做到这一点吗
请注意,我使用的是Saxon处理器,因此我可以使用特定于该处理器的功能,例如,如果有帮助的话,我可以调用一些java
谢谢。这是一个使用XSLT 2.0的隧道参数的解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<!-- identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="top">
<thing>
<upper>
<xsl:apply-templates>
<xsl:with-param name="tree-id" tunnel="yes" select="'upper-'"/>
</xsl:apply-templates>
</upper>
<lower>
<xsl:apply-templates>
<xsl:with-param name="tree-id" tunnel="yes" select="'lower-'"/>
</xsl:apply-templates>
</lower>
</thing>
</xsl:template>
<xsl:template match="id">
<xsl:param name="tree-id" tunnel="yes"/>
<xsl:copy>
<!-- I want to prepend this with "upper" or "lower" depending which block we're in -->
<xsl:value-of select="concat($tree-id, .)" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您的代码表示version=2.0,但Xalan是XSLT1.0处理器。如果切换到Saxon9并真正使用XSLT2.0,那么可以使用隧道参数,以避免在每个应用模板中传递参数。除此之外,我认为参数是正确的方法。@MartinHonnen对不起,我是说Saxon。。。我现在使用的是9.1.0.8版,不过我会研究隧道参数,我以前从未见过。太好了,我以前从未见过隧道参数,谢谢。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="top">
<thing>
<upper>
<xsl:apply-templates />
</upper>
<lower>
<xsl:apply-templates />
</lower>
</thing>
</xsl:template>
<xsl:template match="id">
<!-- I want to prepend this with "upper" or "lower" depending which block we're in -->
<xsl:value-of select="text()" />
</xsl:template>
<!-- identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<!-- identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="top">
<thing>
<upper>
<xsl:apply-templates>
<xsl:with-param name="tree-id" tunnel="yes" select="'upper-'"/>
</xsl:apply-templates>
</upper>
<lower>
<xsl:apply-templates>
<xsl:with-param name="tree-id" tunnel="yes" select="'lower-'"/>
</xsl:apply-templates>
</lower>
</thing>
</xsl:template>
<xsl:template match="id">
<xsl:param name="tree-id" tunnel="yes"/>
<xsl:copy>
<!-- I want to prepend this with "upper" or "lower" depending which block we're in -->
<xsl:value-of select="concat($tree-id, .)" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>