我有一个 XML 文件:
<books>
<title>Moby-Dick</title>
<author>Herman Melville</author>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</books>
我想将其转换为:
<books>
<book>
<title>Moby-Dick</title>
<author>Herman Melville</author>
</book>
<book>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
</book>
<book>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</book>
</books>
逻辑是,book
每次我们遇到一个时就创建一个新的title
,并将每个后续的“非标题”节点放入该书中。
以下是我迄今为止尝试过的:
let $books := (
doc("books.xml")/books/* =>
fold-left((array{}, 0), function($acc, $node) {
let
$arr := $acc[1],
$idx := $acc[2]
return
if (name($node) = "title")
then ($arr => array:append($node), $idx+1)
else ($arr => array:put($idx, ($arr($idx), $node)), $idx)
})
)[1]
return
<books>{
for $book in $books
return <book>{$book}</book>
}</books>
但我明白
<books>
<book>
<title>Moby-Dick</title>
<author>Herman Melville</author>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</book>
</books>
旁白: group by
这似乎对解决当前问题没有用,所以我尝试将书籍分组到一个数组中,但我不知道这是否是正确的方法;欢迎任何建议。
如果您可以选择使用 XSLT 2.0+,请使用:
在 XQuery 3.0+ 中可以使用 FLWOR
window
子句来完成。未经测试。