2014-01-13 47 views
4

我有這樣如何使用xquery更新將節點內的文本轉換爲子節點?

<root> 
    <first> 
    First Level 
    <second> 
     second level 
     <third> 
     Third Level 
     </third> 
    </second> 
    <second2> 
     another second level 
    </second2> 
    </first> 
</root> 

如何使用所有節點這個文件,這意味着如果一個節點包含textchild node文本轉換成一個子節點轉換XML文檔(讓我們childtext說)使用XQuery更新

<root> 
    <first> 
    <childtext>First Level</childtext> 
    <second> 
     <childtext>second level</childtext> 
     <third> 
     Third Level 
     </third> 
    </second> 
    <second2> 
     another second level 
    </second2> 
    </first> 
</root> 

這裏是我的嘗試:

let $a := 
<root> 
    <first> 
    First Level 
    <second> 
     second level 
     <third> 
     Third Level 
     </third> 
    </second> 
    <second2> 
     another second level 
    </second2> 
    </first> 
</root> 
return 
copy $i := $a 
modify (
    for $x in $i/descendant-or-self::* 
    return (
    if($x/text() and exists($x/*)) then (
     insert node <childtext> 
     {$x/text()} 
     </childtext> as first into $x 
     (: here should be some code to delete the text only:) 
    ) else() 
) 
) 
return $i 

我無法刪除具有兄弟節點的文本。

+0

首先,我可以用值text()創建節點「childtext」。現在我必須刪除那些仍然存在的舊文本>我不能刪除這個文本。如果我想讓空值的其他子節點也將被刪除。 –

+0

這裏我試圖做的: 讓$一個:= .... 回報 副本$ I:= $一個 修改( 爲$ X $中的I /後裔或自身:: * 回報( 如果($ X /文()和存在($ X/*)),然後( 插入節點 {$ X /文()} 作爲第一個進入$ X, (:這裏應該以某種方式刪除此文本或更新到一個新的水平:) )其他( ) ) ) 返回$ I –

+0

請編輯該代碼你的問題(其公頃這裏是可讀的),並且不要忽略代碼的一部分,因此它不再運行('let $ a:= ....'當然沒有工作代碼)。你現在的代碼有什麼問題? –

回答

3

正如你想要替換一個元素,你應該簡單地使用replace構造,而不是插入新元素並刪除舊元素。似乎要簡單得多我:

copy $i := $a 
modify (
    for $x in $i/descendant-or-self::*[exists(*)]/text() 
    return replace node $x with <childtext>{$x}</childtext> 
) 
return $i 
+0

是的是的,這就是我真正想要的:-)謝謝@dirkk :-) –

+0

嗨Dirkk它只適用於一個文本()。這意味着它不會像 ab ab那樣工作。如何解決它。 –

+1

@PrakashThapa我編輯了我的答案,但我確實看到了你的解決方案。我更新後的答案與以前一樣更好(將條件直接作爲謂詞放入'for'語句中),並且以這種方式尊重多個「text()」元素。我非常喜歡這個解決方案,它的易讀性和性能更高。 – dirkk

0

修改後的解決方案是從@dirkk這裏:

copy $i := $a 
modify (
    for $x in $i/descendant-or-self::* 
    return (
    if($x/text() and exists($x/*)) then (
     if(count($x/text())=1) then (
     replace node $x/text() with <child> {$x/text()}</child> 
    ) else (
     for $j at $pos in 1 to count($x/text()) 
     return 
     replace node $x/text()[$pos] with <child>{$x/text()[$pos]}</child> 

    ) 


    ) else() 
) 
) 
return $i 

再次謝謝。

相關問題