所以我有以下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>
我试图将其结果存储在一个变量中,以便稍后我可以将它与另一个遍历播放列表的查询进行比较,但我对如何将查询结果存储到变量中有点迷失。有帮助吗?感谢。
答案 0 :(得分: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
不等于任何播放列表轨道的return
<noplaylist>
{
for $x in $not-in-pl/@sid
return
<sid sid="{ data($x) }"/>
}
</noplaylist>
属性。
如果要在多个查询中存储中间结果,则需要使用不同的方法,具体取决于您的XQuery处理器/环境。某些XML数据库允许您存储跨查询持久存储的服务器/会话字段。对于其他人,您需要将中间结果存储在文档中。您使用的XQuery处理器是什么?
<强>更新强>:
在XQuery中构造元素有多种方法。您可以使用元素文字,在其中转义XQuery表达式:
return
element noplaylist {
for $x in $not-in-pl/@sid
return
element sid {
attribute sid { data($x) }
}
}
或者您可以使用XQuery元素/属性构造函数:
{{1}}
答案 1 :(得分:0)
for $x in doc("music.xml")/music/songs/song/@sid
where $x != doc("music.xml")//playlists/playlist/track/@sid
return <sid>{data($x)}</sid>
我不确定它是否巧合,但现在才有意义..