2011-05-08 88 views
2

我有一個XML文檔,如:如何統計具有相同名稱的元素? XML - >的Xquery

<root> 
<test> 
    <humans> 
     <names>Tim</names> 
    </humans> 
</test> 
<test> 
    <humans> 
     <names>Jack</names> 
     <names>Jones</names> 
    </humans> 
</test> 
<test> 
    <humans> 
     <names>Tim</names> 
    </humans> 
</test> 
</root> 

,我想指望它是相同的所有名稱:添2,傑克1,瓊斯1 和它應該給一個輸出,如:

<x> Tim </x> 

因爲TIM是最高的名字

我希望你能幫助我......(對不起我的英文不好)

+0

問得好,+1。查看我的答案,獲取兩個完整,簡短和簡單的解決方案(XPath 2.0/XQuery和XSLT 1.0)。 – 2011-05-08 18:10:25

+0

如可以看到的,使用XPath表達式具有更好的便攜性,並且可以在兩個XQuery和XSLT 2.0,和在主機的XPath 2.0的任何語言來使用不變。 – 2011-05-08 19:53:02

回答

5

在XPath 2.0,XSLT 2.0和XQuery使用(完全相同的溶液):

(/*/*/*/names[for $v in ., 
        $cnt in count(/*/*/*/names[. eq $v]) 
       return 
        $cnt 
        eq 
        max(for $n in distinct-values(/*/*/*/names) 
          return 
           count(/*/*/*/names[. eq $n]) 
         ) 
       ] 
    )[1] 

也可以得到這個元件易於與以下XSLT 1.0變換

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:key name="kNamesByVal" match="names" use="."/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "*/*/*/names[generate-id() 
       = 
       generate-id(key('kNamesByVal',.)[1]) 
       ]"> 
    <xsl:sort select="count(key('kNamesByVal',.))" 
    data-type="number" order="descending"/> 

    <xsl:if test="position()=1"> 
     <xsl:copy-of select="."/> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

當以上的XPath 2.0/XQuery表達式或XSLT轉換被評估(施加)所提供的XML文檔

<root> 
    <test> 
     <humans> 
      <names>Tim</names> 
     </humans> 
    </test> 
    <test> 
     <humans> 
      <names>Jack</names> 
      <names>Jones</names> 
     </humans> 
    </test> 
    <test> 
     <humans> 
      <names>Tim</names> 
     </humans> 
    </test> 
</root> 

正確的元素被選中(生產):

<names>Tim</names> 
1
let $xml := <!-- your xml document --> 
return 
(
    for $name in distinct-values($xml//names) 
    order by count($xml//names[. = $name]) descending 
    return <x>{$name}</x> 
)[1] 
+0

這將加載一個文件:'$讓XML:= DOC( 「data.xml中」)' – ceving 2011-05-08 18:40:58

1

岡瑟的解決方案是最好的,如果你想每一個元素算你可以這樣做:

xquery version "1.0"; 

for $x in 
(
    for $name in distinct-values(//names) 
    order by count(//names[. = $name]) descending 
    return <x>{$name}</x> 
) return fn:concat($x, ' - ',xs:string(count(//names[. = $x]))) 

有了結果蒂姆 - 2傑克 - 1 Johons - 1個

相關問題