Как преобразовать текст внутри узла в дочерний узел, используя обновление xquery?
У меня есть документ XML, как
<root>
<first>
First Level
<second>
second level
<third>
Third Level
</third>
</second>
<second2>
another second level
</second2>
</first>
</root>
Как преобразовать этот документ со всеми узлами, это означает, что если узел содержит text
а также child node
преобразовать текст в дочерний узел (скажем, дочерний текст) с помощью xquery-update
<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
Я не мог удалить текст, у которого есть родной узел.
2 ответа
Решение
Поскольку вы хотите заменить элемент, вы должны просто использовать replace
построить, вместо того, чтобы вставить новый элемент и удалить старый. Мне кажется намного проще:
copy $i := $a
modify (
for $x in $i/descendant-or-self::*[exists(*)]/text()
return replace node $x with <childtext>{$x}</childtext>
)
return $i
Модифицированное решение от @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
Еще раз, спасибо.