2015-03-31 91 views
1

所以我有以下XML文件:如何比較xml文件中的兩個元素?

<!DOCTYPE music SYSTEM "music.dtd"> 
<music> 
<songs> 
    <song sid = "s1" time = "2:04" year = "1994"> 
    <title>Thriller </title> 
    <artist>Michael </artist> 
     <composers> 
      <composer>Michael</composer> 
     </composers> 
    <album> Thriller album</album> 
    </song> 
    <song sid = "s2" time = "2:00" year = "1999"> 
    <title> Billy </title> 
    <artist> Thomas </artist> 
    <composers> 
     <composer> Rick </composer> 
    </composers> 
    <album> The one </album> 
    </song> 
    <song sid = "s3" time = "1:50" year = "2000"> 
     <title> Down </title> 
     <artist> PJ </artist> 
     <composers> 
     <composer>Jerry </composer> 
     </composers> 
     <album>Forty </album> 
    </song> 
</songs> 
<playlists> 
    <playlist pid = "p1" creator = "Tom"> 
    <track sid = "s1"/> 
    </playlist> 
</playlists> 


</music> 

我想要做的是從沒有在播放列表中的歌曲讓所有SID 所以在這個xml文件,我想有一個查詢的回報是sid:s2和s3,因爲這兩者都不在播放列表中,並且因爲s1在播放列表中,所以不應該返回。

我試圖用這個查詢:

for $x in doc("music.xml")/music/songs/song/@sid 
    return <sid>{data($x)}</sid> 

我是想的,其結果存儲在一個變量,所以我以後可以把它比作另一個查詢這將穿越的播放列表,但是我在如何將查詢結果存儲到變量中有點遺憾。任何幫助?謝謝。

回答

2

您可以使用let子句在查詢中綁定變量。下面是一個有幾個中間變量的例子:

let $doc := doc("music.xml")/music 
let $in-pl := $doc/playlists/playlist/track 
let $not-in-pl := $doc/songs/song[fn:not(@sid = $in-pl/@sid)] 
for $x in $not-in-pl/@sid 
return <sid>{data($x)}</sid> 

這裏的關鍵表達式是$doc/songs/song[fn:not(@sid = $in-pl/@sid)]。這使用通用的相等比較操作=,它可以比較序列(0或更多項目)。 fn:not()函數否定比較結果,因此此表達式選擇所有song元素,其中@sid不等於任何播放列表軌道的@sid屬性。

如果要跨多個查詢存儲中間結果,則需要根據您的XQuery處理器/環境採用不同的方法。一些XML數據庫允許您存儲遍歷查詢的服務器/會話字段。對於其他人,您需要將中間結果存儲在文檔中。你在使用什麼XQuery處理器?

更新

有多種方式來構建它的元素。您可以使用元素的文字,裏面逃脫他們的XQuery表達式:

return 
    <noplaylist> 
    { 
    for $x in $not-in-pl/@sid 
    return 
     <sid sid="{ data($x) }"/> 
    } 
    </noplaylist> 

,或者您可以使用XQuery元素/屬性構造函數:

return 
    element noplaylist { 
    for $x in $not-in-pl/@sid 
    return 
     element sid { 
     attribute sid { data($x) } 
     } 
    } 
0

um..so我想這:

for $x in doc("music.xml")/music/songs/song/@sid 
    where $x != doc("music.xml")//playlists/playlist/track/@sid 
    return <sid>{data($x)}</sid> 

我不知道這是否巧合,但現在有道理..

+0

這也可以!如果要在變量中捕獲該表達式的結果,請在它之前添加'let $ results:=',並在其後面添加'return $ results'(或其他表達式)。 XQuery非常靈活;) – joemfb 2015-03-31 17:02:51

+0

看起來像你的問題得到了切斷 – joemfb 2015-03-31 17:04:35

+0

我將如何返回它作爲 user125535 2015-03-31 17:07:05