簡體   English   中英

根據xslt 1.0中for-each循環的sort函數對節點進行計數

[英]Count nodes based on the sort function of for-each loop in xslt 1.0

輸入xml具有以下層次結構。

<a>  
 <b>
  <b1>3</b1> 
  <c> 
    <d>
    <d1>13</d1>
    <d2>text1</d2> 
    </d>
    <d>
    <d1>14</d1>
    <d2>text2</d2>
    </d>   
    <d>
    <d1>12</d1>
    <d2>text3</d2> 
    </d>
  </c>  
 </b>  
 <b>
  <b1>2</b1> 
  <c>  
    <d> 
    <d1>11</d1>
    <d2>text5</d2>
    </d>
    <d>
    <d1>10</d1>
    <d2>text4</d2>
    </d>
  </c>  
 </b> 
  ---- and so on.
</a>

我有一個xsl模板,其中的一部分看起來像

    <xsl:for-each select="a/b">
    <xsl:sort select="b1" data-type="number"/>
    ----- other mapping---
     <xsl:for-each select="c/d">
     <xsl:sort select="d1" data-type="number"/>
       <xsl:variable name="cnt">
       <xsl:value-of select="count(preceding::../../c/d)"/>
      </xsl:variable>
     ------ other mapping------
     </xsl:for-each>
    </xsl:for-each>

現在,即使在應用了sort函數之后,count函數也遵循輸入xml中“ d”的順序,而不是基於for-each語句中“ d”的排序升序。 for-eg在元素b的循環2中,即b [position()= 2],盡管應該為2,但我正在得到cnt = 3

上一條::軸僅按文檔順序查看節點-節點實際在輸入中的順序。 它不會像當前序列或當前排序順序那樣考慮任何東西。

如果您真的想按排序順序計算當前元素之前有多少<d>元素,那么您可以知道排序元素之前的每個元素的值應比當前元素的值低,從而做到這一點:

<xsl:variable name="d1" select="number(d1)" />
<xsl:value-of select="count(../d[number(d1) &lt; $d1])" />

但是xslt中已經有一個函數,它將以for-each循環的排序順序為您提供當前節點的position() ,即position()函數。 它開始計數為1,因此如果您想知道當前節點之前有多少個節點,則需要減去一個:

<xsl:for-each select="a/b">
    <xsl:sort select="b1" data-type="number" />
    ----- other mapping---
    <xsl:for-each select="c/d">
        <xsl:sort select="d1" data-type="number" />
        <xsl:variable name="cnt">
            <xsl:value-of select="position() - 1" />
        </xsl:variable>
        ------ other mapping------
    </xsl:for-each>
</xsl:for-each>

這來自xslt 1.1規范,它比xslt 1.0規范更好地描述了它,但是在xslt 1.0中也是如此:

[上下文位置是上下文項在當前正在處理的項目序列中的位置。 每當上下文項更改時,它也會更改。 當使用諸如xsl:apply-templates或xsl:for-each之類的指令來處理項目序列時,該序列中的第一個項目的上下文位置為1,第二個項目的上下文位置為2,等等。]上下文位置由XPath表達式position()

從您的進一步注釋中,您似乎希望得到一個數字,該數字代表兩個for循環中當前節點的總體順序(以for循環的排序順序)。

您可以使用我的第一種方法:通過使用'<'比較值來按排序順序計算在此節點之前的節點。

然后,您的XSL變為:

<xsl:for-each select="a/b">
    <xsl:sort select="b1" data-type="number" />
    ----- other mapping---
    <xsl:for-each select="c/d">
        <xsl:sort select="d1" data-type="number" />
        <xsl:variable name="me" select="." />
        <xsl:variable name="cnt">
            <xsl:value-of select="count(../d[number(d1) &lt; number($me/d1)]) + count(../../../b/c/d[number(../../b1) &lt; number($me/../../b1)])" />
        </xsl:variable>
        ------ other mapping------
    </xsl:for-each>
</xsl:for-each>

我認為這就是您所描述的。 如果您仍然想要其他東西,那么我認為您的問題不是很清楚-考慮到您的示例輸入文件,請准確描述您以什么順序尋找的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM