Xml XSL从根节点计数节点

Xml XSL从根节点计数节点,xml,xslt,Xml,Xslt,我的XML是完全递归的,因为其中的每个元素都是一个“项”,类型由一个“type”属性描述。在我的XSL中,我希望能够确定我所处的迭代级别,或者换言之,我当前处于根的多少级别。我不知道该怎么做 XML示例: <Questionnaire> <Item ItemType="Group"> <Caption>ABC</Caption> <Item ItemType="Group">

我的XML是完全递归的,因为其中的每个元素都是一个“项”,类型由一个“type”属性描述。在我的XSL中,我希望能够确定我所处的迭代级别,或者换言之,我当前处于根的多少级别。我不知道该怎么做

XML示例:

<Questionnaire>
    <Item ItemType="Group">
        <Caption>ABC</Caption>
        <Item ItemType="Group">
            <Caption>DEF</Caption>
            <Item ItemType="Question">
                <Caption>What's Wrong?</Caption>
            </Item>
        </Item>
    </Item>
    <Item ItemType="Group">
        <Caption>QRS</Caption>
        <Item ItemType="Group">
            <Caption>TUV</Caption>
            <Item ItemType="Question">
                <Caption>What's Wrong?</Caption>
            </Item>
        </Item>
        <Item ItemType="Group">
            <Caption>XYZ</Caption>
            <Item ItemType="Question">
                <Caption>What's Wrong?</Caption>
            </Item>
        </Item>
    </Item>
</Questionnaire>

基础知识
DEF
怎么了?
QRS波
TUV
怎么了?
XYZ
怎么了?
XSL示例:

<xsl:template match="/Questionnaire">
    <xsl:for-each select="Item">
        <fieldset>
            <legend><xsl:value-of select="Caption" /></legend>
            <xsl:call-template name="ItemTemplate" />
        </fieldset>         
    </xsl:for-each>
</xsl:template>

<xsl:template name="ItemTemplate">
    <xsl:if test="@ItemType != 'Question'">
        <ol>
            <xsl:for-each select="Item">
                <li>
                    <xsl:value-of select="Caption" />
                    <xsl:call-template name="ItemTemplate" />
                </li>
            </xsl:for-each>
        </ol>
    </xsl:if>
</xsl:template>

  • 
    (这很深)
    
  • 第三个模板通过递归遍历树来进行计数。上面的此摘录获取变量中的计数:

        <xsl:variable name="Count">
            <xsl:call-template name="count">
                <xsl:with-param name="Node" select="."/>
                <xsl:with-param name="PrevCount" select="1"/>
            </xsl:call-template>
        </xsl:variable>
    
    
    
    这将显示:

         (This is <xsl:value-of select="$Count"/> deep)
    
    (这很深)
    
    一旦您意识到如何通过执行递归循环进行计数,这并不困难。:-)

    
    (这很深)
    
  • 第三个模板通过递归遍历树来进行计数。上面的此摘录获取变量中的计数:

        <xsl:variable name="Count">
            <xsl:call-template name="count">
                <xsl:with-param name="Node" select="."/>
                <xsl:with-param name="PrevCount" select="1"/>
            </xsl:call-template>
        </xsl:variable>
    
    
    
    这将显示:

         (This is <xsl:value-of select="$Count"/> deep)
    
    (这很深)
    
    一旦您意识到如何通过执行递归循环进行计数,这并不困难。:-)

    这个

    count(ancestor::Item)
    
    顺便说一句,在XSLT中使用
    ,而不是命名模板和
    更为惯用

    count(ancestor::Item)
    

    顺便说一句,在XSLT中使用
    比使用命名模板和
    更为惯用。我能想到的最简单的解决方案是在
    项模板
    中定义
    参数
    深度,然后使用
    0
    的参数调用
    (最初)以及随后的
    $depth+1

    以下是我的修改:

      <xsl:template match="/Questionnaire">
        <xsl:for-each select="Item">
          <fieldset>
            <legend><xsl:value-of select="Caption" /></legend>
            <xsl:call-template name="ItemTemplate">
              <xsl:with-param name="depth" select="1" />
            </xsl:call-template>
          </fieldset>                     
        </xsl:for-each>
      </xsl:template>
    
      <xsl:template name="ItemTemplate">
        <xsl:param name="depth" />
        <xsl:if test="@ItemType != 'Question'">
          <ol>
            <xsl:for-each select="Item">
              <li>
                <xsl:value-of select="Caption" />
                <xsl:value-of select="$depth" />
                <xsl:call-template name="ItemTemplate">
                  <xsl:with-param name="depth" select="1+$depth" />
                </xsl:call-template>
              </li>
            </xsl:for-each>
          </ol>
        </xsl:if>
      </xsl:template>
    
    
    

  • 我能想到的最简单的解决方案是在
    ItemTemplate
    模板中定义
    param
    深度,然后使用
    0
    (初始)的param
    调用它,然后使用
    $depth+1
    调用它

    以下是我的修改:

      <xsl:template match="/Questionnaire">
        <xsl:for-each select="Item">
          <fieldset>
            <legend><xsl:value-of select="Caption" /></legend>
            <xsl:call-template name="ItemTemplate">
              <xsl:with-param name="depth" select="1" />
            </xsl:call-template>
          </fieldset>                     
        </xsl:for-each>
      </xsl:template>
    
      <xsl:template name="ItemTemplate">
        <xsl:param name="depth" />
        <xsl:if test="@ItemType != 'Question'">
          <ol>
            <xsl:for-each select="Item">
              <li>
                <xsl:value-of select="Caption" />
                <xsl:value-of select="$depth" />
                <xsl:call-template name="ItemTemplate">
                  <xsl:with-param name="depth" select="1+$depth" />
                </xsl:call-template>
              </li>
            </xsl:for-each>
          </ol>
        </xsl:if>
      </xsl:template>
    
    
    

  • 甚至比我的建议更好。:-)但我的代码是一个很好的选择,它可能用于更复杂的计数。这正是我需要它做的。谢谢。比我的建议还要好。:-)但我的代码是一个很好的选择,它可能用于更复杂的计数。这正是我需要它做的。谢谢