2008-09-30 66 views
10

如何計算XSLT中節點中的不同值?如何計算節點中的不同值?

例子:我希望計算節點國家現有的國家數目,在這種情況下,這將是3

<Artists_by_Countries> 
    <Artist_by_Country> 
     <Location_ID>62</Location_ID> 
     <Artist_ID>212</Artist_ID> 
     <Country>Argentina</Country> 
    </Artist_by_Country> 
    <Artist_by_Country> 
     <Location_ID>4</Location_ID> 
     <Artist_ID>108</Artist_ID> 
     <Country>Australia</Country> 
    </Artist_by_Country> 
    <Artist_by_Country> 
     <Location_ID>4</Location_ID> 
     <Artist_ID>111</Artist_ID> 
     <Country>Australia</Country> 
    </Artist_by_Country> 
    <Artist_by_Country> 
     <Location_ID>12</Location_ID> 
     <Artist_ID>78</Artist_ID> 
     <Country>Germany</Country> 
    </Artist_by_Country> 
</Artists_by_Countries> 

回答

24

如果你有一個大的文件,你可能想使用「Muenchian法」,它通常用於分組,以識別不同的節點。聲明索引你想是不同的值來計算的事情的關鍵:

<xsl:key name="artists-by-country" match="Artist_by_Country" use="Country" /> 

然後你就可以使用得到具有不同國家的<Artist_by_Country>元素:

/Artists_by_Countries 
    /Artist_by_Country 
    [generate-id(.) = 
    generate-id(key('artists-by-country', Country)[1])] 

,你可以數得過來通過將其打包到count()函數的調用中。

當然,在XSLT 2.0,它是那樣簡單

count(distinct-values(/Artists_by_Countries/Artist_by_Country/Country)) 
3

嘗試是這樣的:

count(//Country[not(following::Country/text() = text())]) 

「給我所有國家節點沒有以下國家的匹配文字的計數「

該表達式的有趣位IMO是following軸。

你也許還刪除第一個/text(),並與.

+0

如果節點進行排序和類似國家的值是連續的,因此這隻會工作。 – dacracot 2008-09-30 14:38:04

+3

不,它會一直工作。以下::對整個文檔起作用,如果在上下文之後有任何國傢俱有相同的值,則該節點將不被計數。 – 2008-09-30 14:59:01

+0

這應該是被接受的答案,但2.0選項對於可以使用它的人來說非常有用。 – Moss 2018-01-24 06:38:23

6

更換第二在XSLT 1.0,這不是很明顯,但下面應該給你的需求的想法:

count(//Artist_by_Country[not(Location_ID=preceding-sibling::Artist_by_Country/Location_ID)]/Location_ID) 

XML中的元素越多,需要的時間就越長,因爲它會檢查每個單元素的每個前一個兄弟元素。

0

如果您在國家第一次出現時可以控制xml代,則可以向country節點添加一個屬性,如distinct ='true'將國家標記爲「used」,並且不會隨後添加distinct屬性if你再次遇到那個國家。

然後,您可以做

<xsl:for-each select="Artists_by_Countries/Artist_by_Country/Country[@distinct='true']" />