我有一个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>我想要做的是将这2个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>我所做的是得到所有乐队的细节部分,并列出所有相关的专辑由该乐队生产。但是,由于我使用的是XQuery1.0,所以将专辑按类型分组是非常令人沮丧的!
发布于 2014-05-20 13:36:32
以下操作应该使用纯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是一个特定的乐队有一个特定类型的专辑序列。
发布于 2014-05-20 11:57:13
下面是在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
}
}
}
}https://stackoverflow.com/questions/23750621
复制相似问题