计数器在for-each中,position()没用

时间:2013-08-26 17:16:53

标签: xml xslt

如何在XSLT中使用不使用position()的计数器? 例如: XML

<product type="A" name="pepe"/>
<product type="B" name="paco"/>
<product type="A" name="Juan"/>
<product type="B" name="Edu"/>
<product type="A" name="Lauren"/>

我想按顺序显示所有类型“A”:

1.pepe
2.Juan
3.Lauren

xsl就是那样的

<xsl:for-each select="./products">
<xsl:if test="./products/product/@type="A"">
                    <tr>
<xsl:value-of select="position()"/>
<xsl:value-of select="./product/@name"/>  
                    </tr> 
</xsl:if>  
</xsl:for-each>

1 个答案:

答案 0 :(得分:6)

position()函数是上下文相关的 - 它为您提供“当前节点列表”中当前节点的位置,即当前select表达式提取的节点列表{ {1}}或for-each。所以,如果你做了像

这样的事情
apply-templates

然后您将获得<xsl:for-each select="product"> <xsl:if test="@type = 'A'"> <li><xsl:value-of select="position()"/>: <xsl:value-of select="@name" /></li> </xsl:if> </xsl:for-each> 值1,3和5,因为position()会选择所有五个产品元素。但是,如果您将select测试放在@type表达式中:

select

然后您将获得第1,2和3位,因为<xsl:for-each select="product[@type = 'A']"> <li><xsl:value-of select="position()"/>: <xsl:value-of select="@name" /></li> </xsl:for-each> 仅处理for-each为A的三个产品元素,而不是全部五个。


在一个更复杂的情况下,你真的需要处理所有 @type元素(例如,如果你正在做类型A的那些和类型B不同的东西,但需要保持文档顺序)然后你需要用product轴做一个技巧,例如

preceding-sibling::

使用与此<xsl:if test="@type = 'A'"> <xsl:value-of select="count(preceding-sibling::product[@type = 'A']) + 1" /> </xsl:if> 相同的product显式计算前面@type个元素的数量。