使用position来计算节点 - 有时枚举从0开始而不是1

时间:2011-05-17 06:41:00

标签: xml xslt

嘿伙计们,  我有一个相当clumbsy的xslt片段,我用它来将SOAPUI测试用例转换为更易读的格式。目前,它使用以下

枚举测试用例

<xsl:value-of select="position()-3"/>

我的问题有时,测试用例枚举从0开始,有时从1开始。我不明白为什么会发生这种情况?它与位置选择器的实现方式有关吗?是否有更简洁的方法来计算节点的实例?

非常感谢,

理查德

以下是完整的代码 - 没有样式。

`

  <!-- Edited by XMLSpy® -->
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:con="http://eviware.com/soapui/config">
    <xsl:output method="html" encoding ="utf-8"/>
    <xsl:template match="/">
      <html>
        <head>
          <script type="text/javascript">
            function toggleDiv(divid){
                var ele = document.getElementById(divid);

                if(ele.style.display == 'none')
                    { 
                        ele.style.display = 'block';
                    }
                else
                    {
                        ele.style.display = 'none';
                    }
                }
          </script>  

            <style type="text/css"></style>

        </head>

        <body>

          <xsl:apply-templates/>

          <div class="help">This report is generated automatically by a scheduled job running on Richard Fortune's machine. The SOAPUI project files it references are located in sourcecontrol SVN (https://svn.xxx.xxxxxx.com/svn/network/TEST). These reports are generated daily as the projects they reference are subject to change.</div>

        </body>
      </html>

    </xsl:template>

    <xsl:template match="con:soapui-project">
     <div><h1>Project Name : <xsl:value-of select="@name"/></h1></div> 
      <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="con:testSuite">    

    <xsl:if test="con:description=''">
                <p class="warn"> (RICHARD - PLEASE PROVIDE A DESCRIPTION!!)</p>
    </xsl:if>       
      <div id="content" onmousedown="toggleDiv('{position()}');"><h2 class="ex">TestSuite:  <xsl:value-of select="@name"/></h2></div>
      <br>
        <p class="descSuite"><b>Suite Description: </b><xsl:value-of select="con:description"/></p>
      </br>

      <div style="display:none" id="{position()}"><xsl:apply-templates />
      </div>
    </xsl:template>


    <xsl:template match="con:testCase">

        <ul>
          <li class="tc"><b>
            (#<xsl:value-of select="position()-3"/>) Testcase: </b><xsl:value-of select="@name"/>
          </li>

          <xsl:if test="con:description=''">
            <p class="warn">(Gentle reminder Richard - PLEASE PROVIDE A DESCRIPTION!!)</p>
          </xsl:if>

          <p class="descTc">
            <strong><i>Description:</i></strong> <xsl:value-of select="con:description"/>
          </p>
          <ol class="step">
          <xsl:for-each select="con:testStep"><li>TestStep: <xsl:value-of select="@name"/> </li></xsl:for-each>
          </ol>

        </ul>
        <xsl:apply-templates />

    </xsl:template>


    <xsl:template match="*"></xsl:template>


  </xsl:stylesheet>

`

3 个答案:

答案 0 :(得分:2)

我建议你使用count()

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

这将返回节点相对于其所有兄弟元素的当前位置(从1开始)。

position()可能不是正确的方式,具体取决于具体情况。

答案 1 :(得分:1)

position()的问题是它可以(并且经常)包含您不期望的节点,例如文本甚至空白节点,如果读取XML保留它的话。

根据您的确切要求,您可以计算前一个兄弟姐妹的数量(如@empo所述),或者可能值得查看<xsl:number>指令。

答案 2 :(得分:1)

以下是使用<xsl:number>的方式,这比使用count()更有效:

<li class="tc">
  <b>(#<xsl:number/>) Testcase: </b><xsl:value-of select="@name"/>
</li>

就这么简单!默认情况下,<xsl:number>计算同一节点类型的节点(在本例中为元素)和与上下文节点相同的元素名称...我相信这就是你想要的。因此它会计算<con:testCase>个元素。