我有像
这样的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
请帮我做这个
答案 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">&#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, '
')"/>
</xsl:template>
</xsl:stylesheet>
此转换会产生正确的结果:
1 data1
2 data2
3 data3
4 data4
5 data5
6 data6
7 data7
请注意:
使用<xsl:strip-space elements="*"/>
指示XSLT处理器丢弃任何仅限空格的文本节点。
使用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在他的回答中所指出的,这假定您的原始文档没有仅限空格的节点。在他的回答中,他通过从输入文档中删除所有仅空白节点(使用

指令)并在连接结束时附加新行字符({{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:请提供理由。如果这是错误的,请另外证明。