与问题here相关。
我有以下格式的XML输入:
<book>
<chapter>
...
</chapter>
</book>
我目前正在输出类似的内容:
<div class="book" id="book-3">
<div class="chapter>
...
</div>
</div>
使用规则<div class="book" id="book-{position()}">
创建图书ID。这样id的值就会在每个<book>
节点上递增。
我想输出表格:
<div class="book" id="book-3">
<div class="chapter" id="book-3-chapter-7">
...
</div>
</div>
我一直在尝试使用从父级检索id属性并将其输出到子级中的规则。只是当我问这个问题时,我才意识到,"../@id"
永远不会匹配,因为源XML中的属性不存在,只有输出。
尝试将parent属性用作id的一部分可能不是“XSLT方式”。因此,即使有办法访问输出,这可能是错误的方法。
一旦用他们的id创建了章节标签,我想要遵循相同约定的章节元素的子节点(因此它们将具有<div id="book-2-chapter12-verse212">
)。 id将由单独的Java应用程序用于链接到文档,因此遵循约定很重要(即生成的id不起作用)。
使用XSLT创建这个嵌套递增计数器的最佳方法是什么?
P.S。这个问题的标题可能与我真正想要提出的问题相差甚远,但我不知道XSLT是否足以提出正确的问题。请随时编辑或建议更好的标题。
这意味着有一些答案可以解决我的(糟糕的)原始问题以及一个理解我发现难以表达的意图的答案。我接受了后者。
我希望得到答复的其他人认为这是可以接受的,如果有任何建议如何处理首先提出错误的问题,我会很高兴听到他们的意见。
答案 0 :(得分:3)
你应该看一下xsl:number element。它有一堆格式化和分组结构来完成你试图识别的计数和标签的种类。
This XML.com article解释了如何使用某些属性为书籍,章节,部分等生成多级数字(计数)。
类似的东西:
<xsl:number format="1. " level="multiple" count="book|chapter|verse"/>
在该节目的模板中应用会产生: 2.12.212
答案 1 :(得分:2)
我可能会在模板中添加一个参数,并在apply-templates中使用with-param将其传递下去。避免所有歧义。
<xsl:template match="..."> <!-- the child match -->
<xsl:parameter name="parentId"/>
<child id="{$parentId}-@id">
<!-- code involving $parentId -->
</child>
</xsl:template>
等等:
<xsl:apply-templates select="child">
<xsl:with-param name="parentId" select="@id"/>
</xsl:apply-templates>
另一种选择是在孩子身上使用..
等 - 也许在@id
(来自两个地方)使用模板匹配,以避免重复。
答案 2 :(得分:0)
我会为此目的使用通用函数:
<xsl:template match="*">
<xsl:copy>
<xsl:attribute name="id">
<xsl:call-template name="compute-id"/>
</xsl:attribute>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template name="compute-id">
<xsl:param name="curr-elem" select="."/>
<xsl:param name="id" select="''"/>
<xsl:choose>
<xsl:when test="$curr-elem/..">
<xsl:call-template name="compute-id">
<xsl:with-param name="curr-elem" select="$curr-elem/.."/>
<xsl:with-param name="id">
<xsl:value-of select="concat(name($curr-elem), count($curr-elem/preceding-sibling::*[name()=name($curr-elem)])+1)"/>
<xsl:if test="$id != ''">
<xsl:value-of select="concat('-', $id)"/>
</xsl:if>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$id"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>