4

我正在使用 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 标签上做了一个应用模板,如果 a1 标签有一个等于 a1 的后续兄弟,我什么也不做。我认为必须有一种方法来计算带有前面兄弟的标签(但是如何确保只计算相应的标签?)

任何提示将不胜感激!

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

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

那么它应该是 4,而不是 6:

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

3 回答 3

9

你的问题不是很清楚。“对应的
” 应该是什么?在当前一个之前计算所有将是:a1

 count(preceding-sibling::a1) 

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

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

要仅计算 a1 节点序列中的主同级 a1,请尝试以下操作:找到第一个不是 a1 的节点。

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

惯用的结果是计算当前 a1 之前的所有节点减去第一个非 a1 之前的节点数 + 这个节点本身。

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

或没有变量:

<xsl:value-of 
      select="count(preceding-sibling::*)
             -  count( preceding-sibling::*[not (self::a1)][1]
                      /preceding-sibling::*
                      | preceding-sibling::*[not (self::a1)][1] )"/>
于 2013-07-13T13:53:50.983 回答
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>

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

于 2013-07-13T14:20:05.177 回答
1

尝试遵循 xpath

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

这意味着:前面 a1 的计数减去前面 b 前面的 a1 计数

于 2013-07-13T14:11:14.627 回答