2013-10-21 50 views
2

我们如何使用/(斜线)分隔的路径来动态地使用xquery创建嵌套元素。使用XQuery和xpath动态创建嵌套元素

例如,

如果XML是像下面结构

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

和如果该参数为文档/页眉/页脚然后节点应该像下面被创建。

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

上面仅是example.Can任何一个可以帮助我在基于输入路径

回答

0

令牌化的路径转换为字符串的序列上提供通用的节点创建。同时遍历输入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> 
+0

由于很多..它的工作。 –

+0

上述代码正在生成不同级别的所需节点。例如,“Document/Header/Footer”的路径应该创建为Header的兄弟而不是Body元素的兄弟。 –

+0

@TaarzanT然后算法如何知道'/'是指“孩子”还是“兄弟姐妹”?几乎每一个约定'/'都意味着“孩子”,所以我认为最好保持这种方式,而不是更新你的路径来创建一个兄弟头文件:'Document/Footer'。 – wst