令牌化的路徑轉換爲字符串的序列上提供通用的節點創建。同時遍歷輸入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>
來源
2013-10-21 20:46:17
wst
由於很多..它的工作。 –
上述代碼正在生成不同級別的所需節點。例如,「Document/Header/Footer」的路徑應該創建爲Header的兄弟而不是Body元素的兄弟。 –
@TaarzanT然後算法如何知道'/'是指「孩子」還是「兄弟姐妹」?幾乎每一個約定'/'都意味着「孩子」,所以我認爲最好保持這種方式,而不是更新你的路徑來創建一個兄弟頭文件:'Document/Footer'。 – wst