2014-01-13 48 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 

再次谢谢。

相关问题