我有一个XSLT脚本,我想在每次调用模板时按顺序编号。所以它的缩写版本看起来有点像:
<xsl:call-template name="insertHeader" />
<xsl:for-each ...>
<xsl:call-template name="insertHeader" />
...
</xsl:for-each>
<xsl:call-template name="insertHeader" />
<xsl:template name="insertHeader>
This is item number <xsl:value-of select="$numberOfInvocations />
</xsl:template>
很明显$ numberOfInvocations的东西不起作用,而且在XSLT中你不能增加一个全局计数器变量,这似乎是一种过程语言中的明显方法。我想在第一次调用模板时打印出1,第二次打印出来,等等。我应该怎样做呢?这在XSLT中是否可以远程实现?
谢谢:)
编辑:所以有一些评论说明这个问题没有明确定义。我想要做的是在(HTML)输出中标记一系列表。我看到这样做的最明显的方法是调用一个函数(你可能会告诉我这里不是一个XSLT向导),每次都会自动增加数字。我认为这看起来很难的原因是因为XSLT本身定义了这些表的出现而不是输入。
这个额外的信息可能没那么多用,因为Dimitre的回答让它听起来更像是永远不会起作用。无论如何,谢谢:)
答案 0 :(得分:6)
在XSLT等函数式语言中,没有定义“计算顺序”。
因此,试图通过“及时”排序对“计算”进行编号是没有意义的,如果尝试通常会产生令人惊讶的结果。
例如,没有任何限制<xsl:apply-templates>
按照与所选节点列表中节点的文档顺序相同的顺序应用模板。这些可以并行完成,意味着以任何顺序。
许多XSLT处理器执行 lazy evaluation
,这意味着某些XSLT指令只会在真正需要时进行评估,而不是根据XSLT样式表中的文本顺序进行评估。通常一些指令根本不会被执行。
有时优化器会执行给定的XSLT指令 两次,因为它决定放弃第一个结果以优化空间利用率。
使用递归(通常)和延续传递样式 CPS或<<生成 em> Monads (更具体地说)。
FXSL库(版本1 - 适用于XSLT 1.0和版本2 - 适用于XSLT 2.0)包含可用于组织此类编号的模板:foldl,foldr,iter,iterUntil, scanl,scanr,...等等。
无论何时精确定义问题(当前情况不是这样),都可以产生这样的编号,但会对结果发出警告。
答案 1 :(得分:4)
您是否尝试过position()
功能?
这是我的一个项目的片段,也许它很有帮助:
<xsl:variable name="count" select="count(../ownedParameter[@name])" />
$<xsl:value-of select="@name" />=null
<xsl:if test="$count > 1 and position()!=last()">,</xsl:if>
您应该可以执行以下操作:
<xsl:template name="insertHeader>
This is item number <xsl:value-of select="position()" />
</xsl:template>
......至少我认为这会奏效。如果没有,您可能需要将count()
调用for-each
块。
答案 2 :(得分:2)
您可以使用递归模板在XSLT 1.0中执行此操作。
但是,这是一个很大但是,模板的名称insertHeader
让我觉得你正在尝试做一些应该完全解决的问题XSLT中的不同方式。
你对此有何意图?也许我们可以为您提供更多XSLTish解决方案。我相信你可以通过使用xsl:number
并在@count
属性中使用适当的模式来解决你的问题(如果它是我认为的那个......)。
XSLT 1.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:call-template name="insertHeader"/>
</xsl:template>
<xsl:template name="insertHeader">
<xsl:param name="num" select="1"/>
<xsl:value-of select="concat('This is item number ', $num, '
')"/>
<xsl:if test="$num < 10">
<xsl:call-template name="insertHeader">
<xsl:with-param name="num" select="$num + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将输出:
This is item number 1
This is item number 2
This is item number 3
This is item number 4
This is item number 5
This is item number 6
This is item number 7
This is item number 8
This is item number 9
This is item number 10
答案 3 :(得分:2)
numberOfInvocations
必须在模板外计算并作为参数给出。
在for-each
内,您可以使用position()
检索迭代编号。
在以下样式表中,我向pos
添加了insertHeader
参数。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:s="uri:sample">
<xsl:output type="text"/>
<s:sample>
<table>Table A</table>
<table>Table B</table>
</s:sample>
<xsl:template match="/">
<xsl:apply-templates select="document('')//s:sample"/>
</xsl:template>
<xsl:template match="s:sample">
<xsl:call-template name="insertHeader">
<xsl:with-param name="pos" select="1"/>
</xsl:call-template>
<xsl:variable name="node-set" select="table"/>
<xsl:variable name="node-set-count" select="count($node-set)"/>
<xsl:for-each select="$node-set">
<xsl:call-template name="insertHeader">
<xsl:with-param name="pos" select="1+position()"/>
</xsl:call-template>
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:call-template name="insertHeader">
<xsl:with-param name="pos" select="2+$node-set-count"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="insertHeader">
<xsl:param name="pos"/>
<xsl:text>This is item number </xsl:text><xsl:value-of select="$pos" />
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
注意:示例文档嵌入在样式表中,因此请将样式表应用于自身以查看结果。
$ xsltproc 3663349.xslt 3663349.xslt
This is item number 1
This is item number 2
Table A
This is item number 3
Table B
This is item number 4
答案 4 :(得分:0)
<xsl:number />
查看树形结构并从上到下对其进行编号
XSLT:<h2><xsl:number />.<xsl:value-of select="/t/tittel" /></h2>
来自xml:
<tittel>e</tittel>
<tittel>ex</tittel>
<tittel>exa</tittel>
<tittel>example</tittel>
变成:
<h2>1. e</h2>
<h2>2. ex</h2>
<h2>3. exa</h2>
<h2>4. example</h2>