我正在使用xpath2的索引值來返回已排序的節點序列中current()的索引。使用SAXON,排序的節點序列是唯一的,但index-of返回兩個值的序列。爲什麼index-of()在應用於一系列唯一節點時返回多個值?
這並非總是發生,只是偶爾發生,但不是因爲任何原因我能找到。有人可以解釋發生了什麼事嗎?
我已經根據例程給出這種奇怪的行爲的數據的一個例子製作了一個最小的例子。
源數據:
<data>
<student userID="1" userName="user1"/>
<session startedOn="01/16/2012 15:01:18">
</session>
<session startedOn="11/16/2011 13:31:33">
</session>
</data>
我的XSL文件把會話節點到排序序列$ orderd在根模板的頂部:
<xsl:template match="/">
<xsl:variable name="nodes" as="node()*" select="/data/session"></xsl:variable>
<xsl:variable name="orderd" as="node()*">
<xsl:for-each select="$nodes">
<xsl:sort select="xs:dateTime(xs:dateTime(concat(substring(normalize-space(@startedOn),7,4),'-',substring(normalize-space(@startedOn),1,2),'-',substring(normalize-space(@startedOn),4,2),'T',substring(normalize-space(@startedOn),12,8)))
)" order="ascending"/>
<xsl:sequence select="."/>
</xsl:for-each>
</xsl:variable>
因爲節點已經按照@startOn排序,但按相反的順序,序列$ orderd應該與文檔排序序列$節點相同,除了相反的順序。
當我使用for-each語句創建輸出時,我發現在使用index-of進行測試時,兩個節點看起來都是相同的。
下面的代碼用於輸出數據(和來自後立即上面的塊):
<output>
<xsl:for-each select="$nodes">
<xsl:sort select="position()" order="descending"></xsl:sort>
<xsl:variable name="index" select="index-of($orderd,current())" as="xs:integer*"></xsl:variable>
<xsl:variable name="pos" select="position()"></xsl:variable>
<session reverse-documentOrder="{$pos}" sortedOrder="{$index}"/>
</xsl:for-each>
</output>
作爲輸出(如下所示)表示的,折射率的函數返回的序列(1, 2),這意味着它將兩個節點視爲相同。我檢查了用於對值進行排序的表達式,並生成了截然不同的日期時間字符串。
<output>
<session reverse=documentOrder="1"
sortedOrder="1 2"/>
<session reverse-documentOrder="2"
sortedOrder="1 2"/>
</output>
謝謝,我想我會使用index-of(在$ orderd中返回生成id($ n),generate-id(current()))。 (Gerritt Imsieke建議在Saxon的幫助列表中。) – 2012-01-30 13:16:44
@DavidR:您並不需要使用'generate-id()',並且可以編寫非常簡單的'index-of()'函數,如我的答案中所示。 – 2012-01-30 14:18:45