您可以使用 XQuery 更新:
update your_table
set xml = xmlquery('
copy $i := $p1
modify (
for $j in $i/a
return insert node $p2 into $j
)
return $i'
passing xml as "p1", xmltype('<b></b>') as "p2"
returning content)
where xmlexists('$p/a' passing xml as "p")
或者用这样一个简单的新节点(如果真的是的话):
update your_table
set xml = xmlquery('
copy $i := $p1
modify (
for $j in $i/a
return insert node $p2 into $j
)
return $i'
passing xml as "p1", xmlelement("b", null) as "p2"
returning content)
where xmlexists('$p/a' passing xml as "p")
db<>fiddle
在文档中阅读有关updating XML data 的更多信息。
我需要 下的所有子节点都在
下
您仍然可以通过 XQuery 更新来做到这一点;不禁想到它可以做得更简单,但这会创建b节点的副本,然后将a下的所有其他节点复制到其中,直接删除a下的那些节点,然后插入新的b - 包括复制的孩子 - 在a 下:
update your_table
set xml = xmlquery('
copy $i := $p1
modify (
for $j in $i/a
return insert node (
copy $k := $p2
modify (
for $l in $j/*
return (
insert node $l into $k/b
)
)
return $k
)
into $j,
delete nodes $i/a/*
)
return $i'
passing xml as "p1", xmltype('<b></b>') as "p2"
returning content)
where xmlexists('$p/a' passing xml as "p");
db<>fiddle 带有一些扩展的样本数据,有和没有子节点。
您可以也可以使用regexp_replace 执行此操作,作为对巴巴罗斯在 cmets 中建议的推进;至少对于小型 XML 文档:
update your_table t
set xml = xmltype(regexp_replace(t.xml.getstringval(), '(<a.*?>)(.*?)(</a>)',
'\1<b>\2</b>\3', 1, 0, 'n'))
where xmlexists('$p/a' passing xml as "p");
db<>fiddle
但由于某种原因,它不适用于getclobval() - 不确定在这个特定版本中这是否很重要。但是,除非该结构非常知名并受到控制,否则这可能会在某些时候做一些奇怪的事情,所以它真的只是为了兴趣。将 XML 作为 XML而不是作为字符串进行操作更安全。
还有 XLST……但其他人可以使用它提出建议。