XPath/XQuery 过程分组莫比迪克日出之夜

问题描述 投票:0回答:1

我有一个 XML 文件:

<xml>
  <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>
</xml>

我想将其转变为:

<xml>
  <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>
</xml>

逻辑是每次遇到

book
时创建一个新的
title
并将所有后续节点放入该书中。

这是我迄今为止尝试过的:

let $books := (
  doc("books.xml")/xml/* => 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 => array:get($idx), $node)), $idx)
  })
)[1] return
  <xml>{for $book in $books return <book>{$book}</book>}</xml>

但是我明白了

<xml>
  <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>
</xml>

旁白:

group by
似乎对解决当前问题没有用,所以我尝试“手动”对书籍进行分组,但我不知道这是否是正确的方法;欢迎任何提示。

xpath xquery
1个回答
0
投票

如果您可以选择使用 XSLT 2.0+,这非常简单:

<xsl:template match="booke" group-starting-with="title">
  <book>
    <xsl:copy-of select="current-group()"/>
  </book>
</xsl:template>

在 XQuery 3.1 中,可以使用 FLWOR

window
子句来完成。

for tumbling window $w in books/*
   start at $s when $s[self::title]
   return <book>{$w}</book>

未测试。

© www.soinside.com 2019 - 2024. All rights reserved.