使用XQuery和xpath动态创建嵌套元素

使用XQuery和xpath动态创建嵌套元素,xquery,Xquery,如何使用/(斜杠)分隔的路径使用xquery动态创建嵌套元素 比如说, 如果XML类似于下面的结构 <Document> <Header> <Body> </Body> </Header> </Document> 如果参数是Document/Header/Footer,那么应该像下面那样创建节点 <Document> <Header> <Body> </Body> <

如何使用/(斜杠)分隔的路径使用xquery动态创建嵌套元素

比如说,

如果XML类似于下面的结构

<Document> <Header> <Body> </Body> </Header> </Document>

如果参数是Document/Header/Footer,那么应该像下面那样创建节点

<Document> <Header> <Body> </Body> </Header> **<Footer> </Footer>** </Document>
***

上面只是一个例子。有人能帮我提供基于输入路径的通用节点创建吗?

将路径标记为字符串序列。同时遍历输入XML树和路径树。如果路径在任何一点上与源树不同,请创建与剩余路径匹配的新子树:

declare function local:make-nested-elements(
  $element-names as xs:string*
) as element()*
{
  if (empty($element-names)) then ()
  else element { $element-names[1] } {
    local:make-nested-elements(subsequence($element-names, 2))
  }
};

declare function local:add-path(
  $xml as node()?,
  $paths as xs:string*
) as node()
{
  let $first := $paths[1]
  let $rest := subsequence($paths, 2)
  return
    if (empty($first)) then $xml
    else if ($xml instance of text()) then $xml
    else if (node-name($xml) = xs:QName($first))
    then element { $first } {
        $xml/@*,
        for $n in $xml/node()
        return local:add-path($n, $rest)
      }
    else element { node-name($xml) } {
        $xml/@*, $xml/node(),
        local:make-nested-elements($paths)
      }
};
输入

let $xml := 
  <Document> 
    <Header>This is a Header
      <Body>Body message</Body> 
    </Header> 
  </Document>
let $path := "Document/Header/Footer/keep/nesting"
return local:add-path($xml, tokenize($path, '/'))
<Document>
   <Header>This is a Header
     <Body>Body message
        <Footer>
          <keep>
            <nesting/>
          </keep>
        </Footer>
      </Body>
    </Header>
</Document>
let$xml:=
这是一个标题
正文信息
let$path:=“文档/页眉/页脚/保留/嵌套”
返回本地:添加路径($xml,tokenize($path,'/'))
输出

let $xml := 
  <Document> 
    <Header>This is a Header
      <Body>Body message</Body> 
    </Header> 
  </Document>
let $path := "Document/Header/Footer/keep/nesting"
return local:add-path($xml, tokenize($path, '/'))
<Document>
   <Header>This is a Header
     <Body>Body message
        <Footer>
          <keep>
            <nesting/>
          </keep>
        </Footer>
      </Body>
    </Header>
</Document>

这是一个标题
正文信息

上述代码正在不同级别生成必需的节点。例如,“文档/页眉/页脚”这样的路径应该创建为页眉的同级,而不是主体元素的同级。@TaarzanT那么,算法如何知道
/
是指“子”还是“同级”?几乎所有的约定
/
都表示“child”,所以我认为最好保持这种方式,而是更新您的路径来创建页眉的同级:
文档/页脚