我有一个XML文件 bands.xml ,如下所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bands>
<band>
<name>Metallica</name>
<nationality>American</nationality>
</band>
<band>
<name>Marilyn Manson</name>
<nationality>American</nationality>
</band>
</bands>
以及另一个列出其相册 albums.xml 的文件,如下所示:
<?xml version="1.0" encoding="ISO-8859-1"?>
<albums>
<album>
<title>Master of Puppets</title>
<band>Metallica</band>
<date>1986</date>
<genre>rock</genre>
</album>
<album>
<title>St. Anger</title>
<band>Metallica</band>
<date>2003</date>
<genre>rock</genre>
</album>
<album>
<title>The Golden Age of Grotesque</title>
<band>Marilyn Manson</band>
<date>2004</date>
<genre>rock</genre>
</album>
<album>
<title>Mechanical Animals</title>
<band>Marilyn Manson</band>
<date>1998</date>
<genre>pop</genre>
</album>
</albums>
我希望将这两个XML文件合并到另一个处理过的XML文件中。 Xquery将列出所有乐队,并在其中列出与该特定乐队相关的所有专辑,按专辑类型对其进行分组(按字母顺序排序)。这在下面的XML文件中进一步说明:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<bands>
<band>
<name>Metallica</name>
<nationality>American</nationality>
<albums genre="rock">
<album date="1986">
<title>Master of Puppets</title>
</album>
<album date="2003">
<title>St. Anger</title>
</album>
</albums>
</band>
<band>
<name>Marilyn Manson</name>
<nationality>American</nationality>
<albums genre="pop">
<album date="1998">
<title>Mechanical Animals</title>
</album>
</albums>
<albums genre="rock">
<album date="2004">
<title>The Golden Age of Grotesque</title>
</album>
</albums>
</band>
</bands>
我设法做的是获取所有乐队的详细信息,并列出该乐队制作的所有相关专辑。但是,由于我使用的是Xquery 1.0,根据类型对专辑进行分组真的很令人沮丧!
答案 0 :(得分:1)
以下应该可以使用纯XQuery 1.0:
declare variable $bandsxml := doc("bands.xml");
declare variable $albumsxml := doc("albums.xml");
<bands>
{
for $findband in $bandsxml/bands/band
return
<band>
{
$findband/name,
$findband/nationality,
let $albums-per-band := $albumsxml/albums/album[band = $findband/name]
for $genre in distinct-values($albums-per-band/genre)
order by $genre
let $albums := $albums-per-band[genre = $genre]
return element {"albums"} {
attribute {"genre"} {$genre},
attribute {"active"} {string-join((xs:string(min($albums/date)), "-", xs:string(max($albums/date))), "")},
attribute {"count"} {count($albums)},
for $album in $albums
return element {"album"} {
attribute {"date"} {$album/date},
$album/title
}
}
}
</band>
}
</bands>
在第一个for循环中,它获得每个波段的所有不同类型。然后它使用此信息,$albums
是具有特定类型的特定乐队的一系列专辑。
答案 1 :(得分:0)
以下是在XQuery 3.0中执行此操作的一种方法:
xquery version "3.0";
let $bands := <bands>
<band>
<name>Metallica</name>
<nationality>American</nationality>
</band>
<band>
<name>Marilyn Manson</name>
<nationality>American</nationality>
</band>
</bands>
let $albums := <albums>
<album>
<title>Master of Puppets</title>
<band>Metallica</band>
<date>1986</date>
<genre>rock</genre>
</album>
<album>
<title>St. Anger</title>
<band>Metallica</band>
<date>2003</date>
<genre>rock</genre>
</album>
<album>
<title>The Golden Age of Grotesque</title>
<band>Marilyn Manson</band>
<date>2004</date>
<genre>rock</genre>
</album>
<album>
<title>Mechanical Animals</title>
<band>Marilyn Manson</band>
<date>1998</date>
<genre>pop</genre>
</album>
</albums>
return
element { 'bands' } {
for $findband in $bands//band
return
element { 'band' } {
$findband/name,
$findband/nationality,
for $findalbum in $albums//album
let $genre := $findalbum/genre/text()
where $findalbum/band = $findband/name
group by $genre
order by $genre
return
element { 'albums' } {
attribute { 'genre' } { $genre },
attribute { 'active' } { fn:min($findalbum/date/text()) ||'-' || fn:max($findalbum/date/text()) },
attribute { 'count' } { fn:count($findalbum) },
for $album in $findalbum
return
element { 'album' } {
attribute { 'date' } { $album/date/text()},
$album/title
}
}
}
}