我想使用XSLT在其父元素中找到当前元素的计数

时间:2017-03-09 12:33:31

标签: xslt xslt-1.0 xslt-2.0

<a>
  <z/>
  <b/>
  <b/>
  <b/>
  <c/>
</a>

当我使用XSLT解析当前节点为'c'时,我想在'a'中找到'b'的计数。
是否可以使用XSLT执行此操作?
我不知道元素名称'b'是什么,即它的前一个兄弟。

3 个答案:

答案 0 :(得分:3)

如果你被定位在c标签上,或者实际调用了什么元素,那么为了得到前面兄弟的计数,你会这样做......

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

编辑:在回答你的评论时,如果你不想计算所有兄弟姐妹的数量,只计算前一个兄弟姐妹的数量,以及那之前具有相同名称的兄弟,你可以试试这个... < / p>

<xsl:value-of select="count(preceding-sibling::*[name() = name(current()/preceding-sibling::*[1])])" />

如果您在一个父级下有多个c个节点,那么这不起作用......

<a>
  <z/>
  <b/>
  <b/>
  <b/>
  <c/>
  <z/>
  <b/>
  <c/>
</a>

在这种情况下,你可以定义一个这样的键,用第一个跟随元素的唯一id用不同的名称对元素进行分组:

<xsl:key name="keyc" match="*" use="generate-id(following-sibling::*[name() != name(current())][1])" />

然后你可以这样计算:

<xsl:value-of select="count(key('keyc', generate-id()))" />

以下是实施中的三个选项....

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="keyc" match="*" use="generate-id(following-sibling::*[name() != name(current())][1])" />

    <xsl:template match="c">
      <c>
         <example1>
             <xsl:value-of select="count(preceding-sibling::*)" />
          </example1>
         <example2>
             <xsl:value-of select="count(preceding-sibling::*[name() = name(current()/preceding-sibling::*[1])])" />
          </example2>
          <example3>
             <xsl:value-of select="count(key('keyc', generate-id()))" />
          </example3>
      </c>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

使用xsl:number。它打印出当前元素的数字,格式化为必需。

有关如何进行计算的各种选项, 例如多级或字母的。

实际上它是一个非常强大的工具。

答案 2 :(得分:0)

  

我想找到&#39; b&#39;在&#39; a&#39;当我的解析当前节点是&#39; c&#39;

让我重新说一下:
您希望计算与<b>处于同一级别的<c>的所有匹配项。

这个XSLT通过使用参数调用<xsl:template>来完成工作:
要计算的元素的local-name(在这种情况下&#39; b&#39;):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output  omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="//c">                           <!-- select the desired target element -->
   <xsl:call-template name="count">
     <xsl:with-param name="elemName" select="'b'" />  <!-- name of the element -->
   </xsl:call-template>
 </xsl:template>

  <xsl:template name="count">                         <!-- count all matching elements before and after -->
   <xsl:param name="elemName" />
   <xsl:value-of select="count(preceding-sibling::*[local-name() = $elemName]) + count(following-sibling::*[local-name() = $elemName])" />
 </xsl:template> 

</xsl:stylesheet>

对于您的示例,输出只是:

  

3