我有这样的XML:
<?xml version="1.0" encoding="UTF-8"?>
<nodes>
<n c="value2"/>
<n>Has a relation to node with value2</n>
<n>Has a relation to node with value2</n>
<n c="value"/>
<n>Has a relation to node with value</n>
<n c="value1"/>
<n>Has a relation to node with value1</n>
</nodes>
我对所有具有变量属性的元素进行排序,然后在 for-each循环中迭代此变量。但是在每个循环结束时,我需要打印那些低于当前处理元素(原始XML)的元素的值,并且没有任何属性。
这意味着:在没有属性的<n>
上调用apply-templates,但是“select”attr。在apply-templates
中无效,可能是因为我现在处于变量循环。
有解决方案吗? 感谢
这是XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="nodes">
<xsl:variable name="sorted">
<xsl:for-each select="n[@c]">
<xsl:sort select="@c"></xsl:sort>
<xsl:copy-of select="."></xsl:copy-of>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="$sorted/n">
<xsl:value-of select="@c"></xsl:value-of>
<xsl:apply-templates select="/nodes/n[2]"></xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="n[not(@c)]">
<xsl:value-of select="."></xsl:value-of>
</xsl:template>
</xsl:stylesheet>
这只是一个例子,所有这些都是更大项目的一部分:)
具有更复杂XPAth的所需输出(现在即使是简单的XPAth也不起作用)是:
Value
Has a relation to node with value
Value1
Has a relation to node with value1
Value2
Has a relation to node with value2
Has a relation to node with value2
现在有点清楚吗?
答案 0 :(得分:0)
一些想法:apply-templates没有select处理当前上下文节点的子节点;在您的输入示例中,n
元素根本没有任何子元素。此外,在您的变量中,您执行复制 - 意味着您创建与输入样本中的节点无关的新节点。因此,虽然我不确定你想要在for-each中使用apply-templates实现你的构造是没有意义的,考虑到你发布的输入样本和你使用的变量。
我怀疑你可以使用XSLT 2.0 for-each-group group-starting-with,如
<xsl:template match="nodes">
<xsl:for-each-group select="n" group-starting-with="n[@c]">
<xsl:sort select="@c"/>
<xsl:value-of select="@c"/>
<xsl:apply-templates select="current-group() except ."/>
</xsl:for-each-group>
</xsl:template>
如果这没有帮助,那么考虑发布一个带有样本数据的小输入样本和您想用XSLT 2.0创建的相应输出样本,然后我们就如何实现这一点提出建议。
[edit]现在你已经发布了一个输出样本,我发布了我之前建议的增强版本:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text"/>
<xsl:template match="nodes">
<xsl:for-each-group select="n" group-starting-with="n[@c]">
<xsl:sort select="@c"/>
<xsl:value-of select="@c"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="current-group() except ."/>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="n[not(@c)]">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
当我使用Saxon 9.3并针对最新的输入样本运行样式表时,结果如下:
value
Has a relation to node with value
value1
Has a relation to node with value1
value2
Has a relation to node with value2
Has a relation to node with value2
这就是你所要求的我认为所以尝试用更复杂的实际输入方法。