2015-11-06 63 views
0

我有一個查詢,從我的clob中提取一些XML節點。如何獲取Oracle XPath表達式中父元素的名稱?

select pid, name, xml from (
select d.pid, d.name 
, EXTRACT(xmltype(d.data), '//ns1:myId', 'xmlns:ns1="http://acme.com/') xml 
from DATA d 
order by d.pid desc 
) 
; 

但我想看看提取的xmlnode的父元素名稱實際上是什麼。我試圖

, EXTRACT(xmltype(d.data), '//ns1:myId/../name()', ...) xml 

, EXTRACT(xmltype(d.data), '//ns1:myId/name()', ...) xml 

, EXTRACT(xmltype(d.data), '//ns1:myId/local-name()', ...) xml 

但甲骨文拒絕所有的F將它們與 「無效令牌」 的錯誤消息。

我的Oracle版本是「11.2.0.3.0」。

回答

1

提取物可以讓你看起來高了路徑,但(如MOS文件301709.1中指出,這是9i的,但似乎仍然有效,除了顯示錯誤):

使用XPath函數名( )返回元素名稱是不可能的,因爲extract()和extractValue()方法當前僅支持返回節點集的XPATH操作。

因此,您不能在當前或父節點上使用name()local-name()等函數。有各種各樣的在該文件中的一個解決方法,它可以稍微簡化ROM其例子:

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() 

演示與兩個:

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>      

但是extract() is deprecated anyway。你可以用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    

如果你需要更復雜的東西,你可以拉任何你從節點水平需要,as shown in this answer;但是從你所說的在這裏是過度的。

+0

當然,'extract'的結果不能向上遍歷。但我想我可以修改XPath表達式,這樣'extract'返回父節點供我檢查。 – towi

+0

@towi - 我的意思是在XPath中,而不是後解壓縮,但這是不正確的;這是不受支持的功能。我已經更新了答案以顯示如何完成。不過,我仍然會在棄用的'extract()'上使用更新的功能。 –

+0

工作。感謝您提供'extract'的附加信息已被棄用。我不明白你的不被棄用的解決方案,但是,當我必須的時候,我會的。它裏面有太多東西,我只在「傳球」中看到過,而且他們總是讓我的眼睛「交叉」。 – towi