La documentation Oracle recommande d'utiliser XQuery pour mettre à jour XML . C'est donc la première chose à essayer.
Tout d'abord, c'est possible avec l'ancienne approche avec fonction. XQuery ci-dessous peut être utilisé à la place de l'appel à XmlUpdate
:
XMLQuery(
'
declare function local:copy-replace($element as element()) {
if ($element/self::node_2) then <node_2/>
else if ($element/self::node_3) then <node_3/>
else if ($element/self::node_4) then <node_4/>
else element {node-name($element)}
{$element/@*,
for $child in $element/node()
return if ($child instance of element())
then local:copy-replace($child)
else $child
}
};
local:copy-replace($p/*)
'
passing x as "p" returning content
) as xcol_2
Une autre variante, plus courte et plus intuitive :
XMLQuery(
'
copy $p2 := $p
modify(
replace value of node $p2/node_root/node_2 with "",
replace value of node $p2/node_root/node_3 with "",
replace value of node $p2/node_root/node_4 with ""
)
return $p2
'
passing x as "p" returning content
) as xcol_3
Et en plus, il est possible de retourner une valeur XML modifiée uniquement si la condition ne correspond pas :
WITH xtbl AS
(SELECT 1 AS xtbl_id,
xmltype ('<node_root>
<node_1>12</node_1>
<node_2>233</node_2>
<node_3>223</node_3>
<node_4>234</node_4>
</node_root>') AS x
FROM Dual
UNION ALL
SELECT 2, xmltype ('<node_root>
<node_1></node_1>
<node_2>233</node_2>
<node_3>223</node_3>
<node_4>234</node_4>
</node_root>')
FROM Dual)
SELECT xtbl_id,
x,
XMLQuery(
'
for $test in $p/*
return
if( empty($p/node_root/node_1/text()) )
then $p
else (
copy $p2 := $p
modify(
replace value of node $p2/node_root/node_2 with "",
replace value of node $p2/node_root/node_3 with "",
replace value of node $p2/node_root/node_4 with ""
)
return $p2
)
'
passing x as "p" returning content
) as xcol_4
FROM xtbl
Il existe donc de nombreuses variantes pour effectuer des opérations sur les valeurs XML, mais cela nécessite une connaissance approfondie de XQuery et XPath qu'une fonction XmlUpdate relativement simple...