XSLT中的变量增量

时间:2010-05-26 12:31:09

标签: xml xslt

我有像

这样的xml文件
<node>
 <elm val="data1"/>
 <elm val="data2"/>
 <elm val="data3"/>
 <elm val="data4"/>
 <elm val="data5"/>
 <elm val="data6"/>
 <elm val="data7"/>
</node>

我需要为这个xml文件编写一个xslt,以显示在像

这样的表格中
  1 dat1
  2 dat2
  3 dat3
  4 dat4
  5 dat5
  6 dat6
  7 dat7

请帮我做这个

5 个答案:

答案 0 :(得分:2)

<xsl:tempate match="node">
  <table>
    <xsl:call-template select="elm"/>
  </table>
</xsl:template>

<xsl:template match="elm">
  <tr>
    <td>
      <xsl:value-of select="count(preceding-sibling::elm) + 1"/>
    </td>
    <td>
      <xsl:value-of select="@val"/>
    </td>
  </tr>
</xsl:template>

或者,如果需要确切的输出,请使用elm的以下模板。

<xsl:template match="elm">
  <xsl:param name="pos" select="count(preceding-sibling::elm) + 1"/>
  <tr>
    <td>
      <xsl:value-of select="$pos"/>
    </td>
    <td>
      <xsl:text>dat</xsl:text>
      <xsl:value-of select="$pos"/>
    </td>
  </tr>
</xsl:template>

或者在文本输出的情况下:

<xsl:tempate match="node">
  <xsl:foreach select="elm">
     <xsl:value-of select="count(preceding-sibling::elm) + 1"/>
     <xsl:text> dat</xsl:text>
     <xsl:value-of select="count(preceding-sibling::elm) + 1"/>
     <xsl:text  disable-output-escaping="yes">&amp;#xA;</xsl:text>
  </xsl:foreach>
</xsl:template>

答案 1 :(得分:2)

这是错误的

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

 <xsl:template match="elm">
     <xsl:value-of select="concat(position(), ' ', @val)"/>
 </xsl:template>
</xsl:stylesheet>

当使用许多XSLT处理器运行时,这将产生以下(不需要的)输出

 2 data1
 4 data2
 6 data3
 8 data4
 10 data5
 12 data6
 14 data7

原因,当模板应用于顶部元素的子元素时,这包括仅为空格的文本节点的子节点 - 每两个连续elm之间的子节点元件。

所以,Oded的解决方案是错误的

这是一个正确的解决方案(也是最短的解决方案之一):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

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

此转换会产生正确的结果

1 data1
2 data2
3 data3
4 data4
5 data5
6 data6
7 data7

请注意

  1. 使用<xsl:strip-space elements="*"/> 指示XSLT处理器丢弃任何仅限空格的文本节点。

  2. 使用XPath concat()函数将位置,数据和NL字符粘合在一起。

答案 2 :(得分:1)

您可以使用position()功能

<xsl:template match="elm">
   <xsl:value-of select="concat(position(), ' ', @val)" />
</xsl:template>

注意:示例中的表格格式与val属性的值不匹配,但我假设您希望两者都相同(第一行的输出应为1 data1而不是1 dat1 <xsl:strip-space elements="*"/>

正如@Dimitre Novatchev在他的回答中所指出的,这假定您的原始文档没有仅限空格的节点。在他的回答中,他通过从输入文档中删除所有仅空白节点(使用&#xA;指令)并在连接结束时附加新行字符({{1}})来处理此问题。

答案 3 :(得分:0)

<xsl:template match="node">
   <table>
      <xsl:apply-templates select="elm"/>
   </table>
</xsl:template>

<xsl:template match="elm">
   <tr>
      <td><xsl:value-of select="position()"/></td>
      <td>dat<xsl:value-of select="position()"/></td>
   </tr>
</xsl:template>

答案 4 :(得分:-1)

XSLT“变量”是不变的变量。设置后,您无法随意更改它们。

围绕它的唯一黑客是使用position()函数和其他“+1”函数,但是你没有获得真正变量的灵活性。

有许多关于XSLT“变量”不可变性的文章。

引用“http://www.xml.com/pub/a/2001/02/07/trxml9.html

上的文章
  

XSLT变量实际上与许多编程语言中的常量有很多共同之处,并且用于类似目的。

XSLT中的计数器是不可能的,因为XSLT不是一种过程语言,它是声明性的。对于downvoter:请提供理由。如果这是错误的,请另外证明。