如何比较 xml 文件中的两个元素?
How to compare two elements in an xml file?
所以我有以下 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 文件中,我想查询 return 是 sid: s2 和 s3 因为这两个都不在播放列表中并且因为 s1 在播放列表中,所以它不应该是 return编辑。
我正在尝试使用此查询:
for $x in doc("music.xml")/music/songs/song/@sid
return <sid>{data($x)}</sid>
我试图将结果存储在一个变量中,这样我以后可以将它与另一个遍历播放列表的查询进行比较,但我对如何将查询结果存储到变量中有点迷茫.有什么帮助吗?谢谢。
您可以使用 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 processor/environment。一些 XML 数据库允许您存储 server/session 字段,这些字段在查询中保持不变。对于其他人,您需要将中间结果存储在文档中。您使用的是什么 XQuery 处理器?
更新:
在 XQuery 中有多种构造元素的方法。您可以使用元素文字,转义其中的 XQuery 表达式:
return
<noplaylist>
{
for $x in $not-in-pl/@sid
return
<sid sid="{ data($x) }"/>
}
</noplaylist>
或者您可以使用 XQuery element/attribute 构造函数:
return
element noplaylist {
for $x in $not-in-pl/@sid
return
element sid {
attribute sid { data($x) }
}
}
嗯..所以我试过了:
for $x in doc("music.xml")/music/songs/song/@sid
where $x != doc("music.xml")//playlists/playlist/track/@sid
return <sid>{data($x)}</sid>
我不确定这是不是巧合,但现在有道理了..
所以我有以下 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 文件中,我想查询 return 是 sid: s2 和 s3 因为这两个都不在播放列表中并且因为 s1 在播放列表中,所以它不应该是 return编辑。
我正在尝试使用此查询:
for $x in doc("music.xml")/music/songs/song/@sid
return <sid>{data($x)}</sid>
我试图将结果存储在一个变量中,这样我以后可以将它与另一个遍历播放列表的查询进行比较,但我对如何将查询结果存储到变量中有点迷茫.有什么帮助吗?谢谢。
您可以使用 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 processor/environment。一些 XML 数据库允许您存储 server/session 字段,这些字段在查询中保持不变。对于其他人,您需要将中间结果存储在文档中。您使用的是什么 XQuery 处理器?
更新:
在 XQuery 中有多种构造元素的方法。您可以使用元素文字,转义其中的 XQuery 表达式:
return
<noplaylist>
{
for $x in $not-in-pl/@sid
return
<sid sid="{ data($x) }"/>
}
</noplaylist>
或者您可以使用 XQuery element/attribute 构造函数:
return
element noplaylist {
for $x in $not-in-pl/@sid
return
element sid {
attribute sid { data($x) }
}
}
嗯..所以我试过了:
for $x in doc("music.xml")/music/songs/song/@sid
where $x != doc("music.xml")//playlists/playlist/track/@sid
return <sid>{data($x)}</sid>
我不确定这是不是巧合,但现在有道理了..