Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment obtenir le nom de l'élément parent dans une expression Oracle XPath ?

L'extraction vous permet de regarder plus haut dans le chemin, mais (comme indiqué dans le document MOS 301709.1 ; qui est pour 9i mais semble toujours valide, à part l'erreur affichée) :

Vous ne pouvez donc pas utiliser le name() , local-name() etc., sur le nœud courant ou parent. Il existe une sorte de solution de contournement dans ce document, qui peut être légèrement simplifiée par rapport à leur exemple :

EXTRACT(xmltype(d.data), '//ns1:myId/..', 
  'xmlns:ns1="http://acme.com/').getRootElement() xml2

Ou sous une forme légèrement différente :

xmltype(d.data).extract('//ns1:myId/..', 
  'xmlns:ns1="http://acme.com/').getRootElement()

Démo avec les deux :

with data (pid, name, data) as (
  select 42, 'Test', '<?xml version="1.0" encoding="ISO-8859-1"?>
  <ns1:root xmlns:ns1="http://acme.com/"><ns1:parent><ns1:myId>1234</ns1:myId></ns1:parent></ns1:root>' from dual
)
select d.pid, d.name
, EXTRACT(xmltype(d.data), '//ns1:myId', 'xmlns:ns1="http://acme.com/') xml
, EXTRACT(xmltype(d.data), '//ns1:myId/..', 'xmlns:ns1="http://acme.com/').getRootElement() xml2
, xmltype(d.data).extract('//ns1:myId/..', 'xmlns:ns1="http://acme.com/').getRootElement() xml3
from DATA d
order by d.pid desc
;

       PID NAME XML                            XML2       XML3     
---------- ---- ------------------------------ ---------- ----------
        42 Test <ns1:myId xmlns:ns1="http://ac parent     parent    
                me.com/">1234</ns1:myId>                      

Mais extract() est obsolète de toute façon . Vous pouvez le faire avec XMLTable :

with data (pid, name, data) as (
  select 42, 'Test', '<?xml version="1.0" encoding="ISO-8859-1"?>
  <ns1:root xmlns:ns1="http://acme.com/"><parent><myId>1234</myId></parent></ns1:root>' from dual
)
select d.pid, d.name, x.*
from data d
cross join xmltable(xmlnamespaces('http://acme.com/' as "ns1"),
  '/ns1:*//myId'
  passing xmltype(d.data)
  columns myId number path '.',
    parent varchar2(20) path './../local-name()'
) x
order by d.pid desc;

       PID NAME       MYID PARENT             
---------- ---- ---------- --------------------
        42 Test       1234 parent              

Si vous avez besoin de quelque chose de plus compliqué, vous pouvez extraire tout ce dont vous avez besoin des niveaux de nœud, comme indiqué dans cette réponse; mais d'après ce que vous avez dit, c'est exagéré ici.