如何计算xsl中相同的前一个兄弟姐妹的数量

时间:2013-07-13 13:19:01

标签: xslt xslt-2.0

我正在使用xslt版本2,我正在尝试将xml转换为fo输出,并且我遇到了特定的问题。

以下是我的输入:

    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>
    <a2/>
    <b/>
    <c/>
    <a1/>
    <a1/>
    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>

从功能上讲,这个数据包含由a1 | a2,b?,c?,d?定义的'集合'列表。

我的问题是我看不出如何计算特定“套装”的a1标签数量。

确实,我已经编写了我的xsl,我得到了类似的输出:

<fo:table>
    <fo:row>
        <fo:cell>b: </fo:cell>
        <fo:cell>b value</fo:cell>
    </fo:row>
    <fo:row>
        <fo:cell>a1: </fo:cell>
        <fo:cell>number of a1 ???</fo:cell> <-- what I am trying to retrieve
    </fo:row>
    <fo:row>
        ...
    </fo:row>
    ...
</fo:table>

我在a1 + | a2标签上做了一个apply-template,如果a1标签有一个等于a1的跟随兄弟,我什么都不做。 我认为必须有一种方法来计算前面兄弟的标签(但是如何确保只计算相应的标签?)

任何提示都将不胜感激!

编辑: 在上面的输入示例中,第一个计数应为2:

    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>

然后应该是4,而不是6:

    <a1/>
    <a1/>
    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>

3 个答案:

答案 0 :(得分:9)

你的问题不是很清楚。
“相应的”应该是什么? 在当前的a1之前计算所有 count(preceding-sibling::a1)

 count(preceding-sibling::a1[/corresponding one/]) 

如果需要,您可以添加谓词,如:

<xsl:variable name="firstnota1" select="preceding-sibling::*[not (self::a1)][1]" />

要仅计算a1节点序列中的主席兄弟a1,请尝试: 找到第一个不是a1的节点。

<xsl:value-of select="count(preceding-sibling::*) 
       -  count($firstnota1/preceding-sibling::* | $firstnota1)"/>

胜过结果,是计算当前a1之前的所有节点减去第一个不是a1 +此节点之前的节点数。

<xsl:value-of 
      select="count(preceding-sibling::*)
             -  count( preceding-sibling::*[not (self::a1)][1]
                      /preceding-sibling::*
                      | preceding-sibling::*[not (self::a1)][1] )"/>

或者没有变量:

{{1}}

答案 1 :(得分:2)

我会使用for-each-group group-adjacent="boolean(self::a1)">例如

<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="root">
  <xsl:for-each-group select="*" group-adjacent="boolean(self::a1)">
    <xsl:choose>
      <xsl:when test="current-grouping-key()">
        <xsl:value-of select="'Count is: ', count(current-group())"/>
      </xsl:when>
      <xsl:otherwise>
        <!-- process other elements here -->
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>

如果输入是

<root>
    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>
    <a2/>
    <b/>
    <c/>
    <a1/>
    <a1/>
    <a1/>
    <a1/>
    <b/>
    <c/>
    <d/>
</root>

然后Saxon 9输出Count is: 2Count is: 4所以它输出你想要的数字(格式严格,不可否认)。如果你没有得到任何输出,那么你发布的元素可能与我选择的元素不同(即root)。或者您使用名称空间,self::a1需要进行调整。

答案 2 :(得分:1)

尝试关注xpath

count(preceding-sibling::a1)-count(preceding-sibling::b[1]/preceding-sibling::a1)

这意味着:在前一个b之前的a1的所有减去计数之前的a1的计数