Java 如何使用递增计数器在XSLT中提供唯一id?

Java 如何使用递增计数器在XSLT中提供唯一id?,java,xslt,xhtml,Java,Xslt,Xhtml,我正在使用XSLT将一个非常大的XML文档转换为(X)HTML。对于一些标记,我将它们转换为。我希望能够为这些标签创建一个唯一的id,使用递增的整数来形成唯一id的一部分 我使用的规则的一个例子是: <xsl:template match="bookcoll/book"> <div class="book"> <xsl:apply-templates/> </div> </xsl:template>

我正在使用XSLT将一个非常大的XML文档转换为(X)HTML。对于一些标记,我将它们转换为
。我希望能够为这些标签创建一个唯一的id,使用递增的整数来形成唯一id的一部分

我使用的规则的一个例子是:

<xsl:template match="bookcoll/book">
    <div class="book">
        <xsl:apply-templates/>
    </div>
</xsl:template>

这个XSLT模板工作得很好。我现在想要的是标签:

<div class="book">;  
成为:

<div class="book" id="book-[COUNTER-VALUE]">  

理想情况下,计数器从1开始,而不是从0开始

我不知道这是否有多大区别,我正在使用Java包javax.xml.parsers和javax.xml.transform来执行实际的转换。我是一个有点XSLT的noob,所以如果有任何相关信息我错过了,请让我知道


如何在XSLT中实现这一点?

自然/惯用/故障保护解决方案是:

<div class="book" id="book-{generate-id()}">

它不是递增的,但保证是唯一的。它将生成HTML有效ID字符串()

编辑:如果必须递增,请执行以下操作:

<!-- in the calling template… -->
<xsl:apply-templates select="bookcoll/book[xpath to filter them if necessary]" />

<!-- …later -->
<xsl:template match="bookcoll/book">
  <div class="book" id="book-{position()}">
    <xsl:apply-templates/>
  </div>
</xsl:template>

您可以使用
format-number()
使
position()
的输出适应您的需要


position()
将返回相对于当前正在处理的“批次”的节点位置。通过显式调用
,您可以确保它们按照您想要的方式编号。

您可以将Java类上的静态方法的调用添加到转换中。。。这是可行的,但也有一些缺点,比如 1) 现在,您的转换与一些Java代码相关联,并且在诸如Oxygen之类的外部工具中更难进行测试/调试(尽管有一些方法可以缓解这种情况)
2) 您必须将状态维护为静态或线程局部变量,这可能会导致各种问题(同步问题、多次执行此操作时有关重置的问题等)

查看position()函数。

正如前面多次建议的,您需要
position()
,但是您必须使用
xsl:for-each对项目进行迭代:

<xsl:template match="bookcoll">
    <xsl:for-each select="book">
        <div class="book" id="book-{position()}">
            <xsl:apply-templates/>
        </div>
    </xsl:for-each>
</xsl:template>

这将产生如下结果:

<div class="book" id="book-1">book1</div>
<div class="book" id="book-2">book2</div>
<div class="book" id="book-3">book3</div>
book1
第二册
第三册
为了


第一册
第二册
第三册

为代码缩进4个空格,如下所示:啊,好多了。我试着用pre和code标签来做,奇怪的事情正在发生。谢谢大家!@Grundlefleck:XSLT的一个(经过大量修改和注释的)版本可以在上找到。我希望我能把它做好,如果不能,改变应该很容易。玩得开心。:-)哦,这里有另一个版本2:。另一种方法(可能)更好,因为如果您忘记为某个标记编写模板(显式优于隐式),它不会导致不需要的元素出现在输出中。其中有一些有趣的新东西(对我来说)供我学习。非常感谢,托马拉克!:-)我已经读过这样做的方法,但是递增是我真正想要的:-(${COUNTER}是我显示它是一个变量的方式(就像bash那样)。编辑问题以消除歧义。
{}
已经在XSLT中进行了变量插值,
$
仅仅表示一个变量。这可能超出了问题的范围。position()增加了2,也就是说,增加了book-2,book-4…我假设我的模板匹配的节点比match=“bookcoll/book”预期的多。您建议我如何计算通过该匹配找到的节点?例如,您可能正在处理
节点之间的空文本节点。这就是为什么我说“显式调用
”。裸
处理它能找到的任何子节点,包括文本节点。转换不会经常出现。它们已经用Java代码启动,不需要执行。你有这项技术的源代码或教程链接吗?我已经在处理
以将软管转换为div。我似乎无法使现有位与for-each循环很好地配合。可以这样做吗?您的XML基本上与我发布的XML示例相匹配吗?如果是,发布的XSL示例应该可以。确实如此,但我还想将
转换为
,并且在这两个方面都遇到了一些问题。不过,谢谢。+1 btw
<bookcoll>
    <book>book1</book>
    <book>book2</book>
    <book>book3</book>
</bookcoll>