2

如何在 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>
4

1 回答 1

6

position()函数是上下文相关的 - 它为您提供当前节点在“当前节点列表”中的位置,即由current or的select表达式提取的节点列表。所以如果你做类似的事情for-eachapply-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>

那么您将获得position()1、3 和 5 的值,因为select选择了所有五个产品元素。但是,如果您将@type测试放在select表达式中:

<xsl:for-each select="product[@type = 'A']">
  <li><xsl:value-of select="position()"/>: <xsl:value-of select="@name" /></li>
</xsl:for-each>

那么您将获得位置 1、2 和 3,因为for-each它仅处理@type为 A 的三个产品元素,而不是所有五个。


在更复杂的情况下,您确实需要处理所有product元素(例如,如果您正在使用 A 类型的元素和 B 类型的元素不同,但需要保持文档顺序),那么您需要用preceding-sibling::轴做一个技巧,例如

<xsl:if test="@type = 'A'">
  <xsl:value-of select="count(preceding-sibling::product[@type = 'A']) + 1" />
</xsl:if>

显式计算与此相同的前面product元素的数量@type

于 2013-08-26T17:51:48.760 回答