2013-10-21 45 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