[英]Count nodes based on the sort function of for-each loop in xslt 1.0
输入xml具有以下层次结构。
<a>
<b>
<b1>3</b1>
<c>
<d>
<d1>13</d1>
<d2>text1</d2>
</d>
<d>
<d1>14</d1>
<d2>text2</d2>
</d>
<d>
<d1>12</d1>
<d2>text3</d2>
</d>
</c>
</b>
<b>
<b1>2</b1>
<c>
<d>
<d1>11</d1>
<d2>text5</d2>
</d>
<d>
<d1>10</d1>
<d2>text4</d2>
</d>
</c>
</b>
---- and so on.
</a>
我有一个xsl模板,其中的一部分看起来像
<xsl:for-each select="a/b">
<xsl:sort select="b1" data-type="number"/>
----- other mapping---
<xsl:for-each select="c/d">
<xsl:sort select="d1" data-type="number"/>
<xsl:variable name="cnt">
<xsl:value-of select="count(preceding::../../c/d)"/>
</xsl:variable>
------ other mapping------
</xsl:for-each>
</xsl:for-each>
现在,即使在应用了sort函数之后,count函数也遵循输入xml中“ d”的顺序,而不是基于for-each语句中“ d”的排序升序。 for-eg在元素b的循环2中,即b [position()= 2],尽管应该为2,但我正在得到cnt = 3 。
上一条::轴仅按文档顺序查看节点-节点实际在输入中的顺序。 它不会像当前序列或当前排序顺序那样考虑任何东西。
如果您真的想按排序顺序计算当前元素之前有多少<d>
元素,那么您可以知道排序元素之前的每个元素的值应比当前元素的值低,从而做到这一点:
<xsl:variable name="d1" select="number(d1)" />
<xsl:value-of select="count(../d[number(d1) < $d1])" />
但是xslt中已经有一个函数,它将以for-each循环的排序顺序为您提供当前节点的position()
,即position()
函数。 它开始计数为1,因此如果您想知道当前节点之前有多少个节点,则需要减去一个:
<xsl:for-each select="a/b">
<xsl:sort select="b1" data-type="number" />
----- other mapping---
<xsl:for-each select="c/d">
<xsl:sort select="d1" data-type="number" />
<xsl:variable name="cnt">
<xsl:value-of select="position() - 1" />
</xsl:variable>
------ other mapping------
</xsl:for-each>
</xsl:for-each>
这来自xslt 1.1规范,它比xslt 1.0规范更好地描述了它,但是在xslt 1.0中也是如此:
[上下文位置是上下文项在当前正在处理的项目序列中的位置。 每当上下文项更改时,它也会更改。 当使用诸如xsl:apply-templates或xsl:for-each之类的指令来处理项目序列时,该序列中的第一个项目的上下文位置为1,第二个项目的上下文位置为2,等等。]上下文位置由XPath表达式
position()
。
从您的进一步注释中,您似乎希望得到一个数字,该数字代表两个for循环中当前节点的总体顺序(以for循环的排序顺序)。
您可以使用我的第一种方法:通过使用'<'比较值来按排序顺序计算在此节点之前的节点。
然后,您的XSL变为:
<xsl:for-each select="a/b">
<xsl:sort select="b1" data-type="number" />
----- other mapping---
<xsl:for-each select="c/d">
<xsl:sort select="d1" data-type="number" />
<xsl:variable name="me" select="." />
<xsl:variable name="cnt">
<xsl:value-of select="count(../d[number(d1) < number($me/d1)]) + count(../../../b/c/d[number(../../b1) < number($me/../../b1)])" />
</xsl:variable>
------ other mapping------
</xsl:for-each>
</xsl:for-each>
我认为这就是您所描述的。 如果您仍然想要其他东西,那么我认为您的问题不是很清楚-考虑到您的示例输入文件,请准确描述您以什么顺序寻找的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.