2015-11-06 65 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