1

我有以下 xml 示例,我想为 n=1 到 5 的每本书输出“book #n name is xxx”。 position() 的计算结果为 1,2,1,2,3,所以我不能使用它功能。谢谢。

<books>
  <cat>
    <book>a</book>
    <book>b</book>
  </cat>
  <cat>
    <book>c</book>
    <book>d</book>
    <book>e</book>
  </cat>
</books>
...
...
<xsl:template match="book">
<!-- I need expression to evaluate as:
book a = 1
book b = 2
book c = 3
book d = 4
book e = 5
-->
    <xls:variable name="idx" select="postition()"/>
    name of book #<xsl:value-of select="$idx"/> is <xsl:value-of select"."/>
</xsl:template>
4

1 回答 1

3

使用

 count(preceding::book) +1

但是请注意,如果可能有嵌套book元素,那么要使用的正确表达式变为:

 count(ancestor::book | preceding::book) +1

或者可以使用<xsl:number>

完整代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="book">
   <xsl:value-of select=
   "concat('book ', ., ' = ', count(preceding::book) +1, '&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<books>
  <cat>
    <book>a</book>
    <book>b</book>
  </cat>
  <cat>
    <book>c</book>
    <book>d</book>
    <book>e</book>
  </cat>
</books>

产生了想要的正确结果

book a = 1
book b = 2
book c = 3
book d = 4
book e = 5

二、使用<xsl:number>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="book">
   <xsl:value-of select="concat('&#xA;book ', ., ' = ')"/>
   <xsl:number level="any" count="book"/>
 </xsl:template>
</xsl:stylesheet>

三、使用position()适当的<xsl:apply-templates>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:apply-templates select="/*/*/book"/>
 </xsl:template>

 <xsl:template match="book">
   <xsl:value-of select="concat('&#xA;book ', ., ' = ', position())"/>
 </xsl:template>
</xsl:stylesheet>

说明

的值position()是当前节点在产生的节点列表中的位置,<xsl:apply-templates>它导致选择此模板进行执行。如果我们使用正确的,<xsl:apply-templates>那么使用position() 可以了。

于 2012-10-26T17:39:04.680 回答