从Oracle中的xml数据中提取值

时间:2016-12-20 14:17:48

标签: xml oracle extract

我需要帮助从我的一个表列中存储的xml数据中提取与标记相对应的数据。下面是我表中的示例xml数据,我需要提取与标记'REQUESTTYPE'对应的值。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE VXIN SYSTEM "VXInData.dtd">
<VXIN>
<REQUESTS>
<REQUEST>
<REQUESTTYPE>ADD</REQUESTTYPE>
<REQUESTNUMBER>12345</REQUESTNUMBER>
<ID>1234567</ID>
<ACCESSLIST>
<ACCESS>
<ACCESSLEVEL>
<AID>123789</AID>
</ACCESSLEVEL>
<PERSONNEL>
<REQUESTEDFOR>
<UID>13579</UID>
<FIRSTNAME>MOBY</FIRSTNAME>
</REQUESTEDFOR>
</PERSONNEL>
</ACCESS>
</ACCESSLIST>
</REQUEST>
</REQUESTS>
</VXIN>

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

一种方法:

declare
   l_xml         xmltype;
   l_requesttype varchar2(30);
begin
   l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?>
<VXIN>
<REQUESTS>
<REQUEST>
<REQUESTTYPE>ADD</REQUESTTYPE>
<REQUESTNUMBER>12345</REQUESTNUMBER>
<ID>1234567</ID>
<ACCESSLIST>
<ACCESS>
<ACCESSLEVEL>
<AID>123789</AID>
</ACCESSLEVEL>
<PERSONNEL>
<REQUESTEDFOR>
<UID>13579</UID>
<FIRSTNAME>MOBY</FIRSTNAME>
</REQUESTEDFOR>
</PERSONNEL>
</ACCESS>
</ACCESSLIST>
</REQUEST>
</REQUESTS>
</VXIN>');

   select x.*
     into l_requesttype
     from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path 'REQUESTTYPE') x;

   dbms_output.put_line(l_requesttype);
end;

正如您所看到的,我删除了对DTD的引用,因为数据库无法访问它。 要使用DTD引用运行此代码,您可以告诉解析器不要查找它。

declare
   l_xml         xmltype;
   l_requesttype varchar2(30);
begin

   execute immediate 'alter session set events =''31156 trace name context forever, level 2''';

   l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE VXIN SYSTEM "VXInData.dtd">
<VXIN>
<REQUESTS>
<REQUEST>
<REQUESTTYPE>ADD</REQUESTTYPE>
<REQUESTNUMBER>12345</REQUESTNUMBER>
<ID>1234567</ID>
<ACCESSLIST>
<ACCESS>
<ACCESSLEVEL>
<AID>123789</AID>
</ACCESSLEVEL>
<PERSONNEL>
<REQUESTEDFOR>
<UID>13579</UID>
<FIRSTNAME>MOBY</FIRSTNAME>
</REQUESTEDFOR>
</PERSONNEL>
</ACCESS>
</ACCESSLIST>
</REQUEST>
</REQUESTS>
</VXIN>');

   select x.*
     into l_requesttype
     from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path
                   'REQUESTTYPE') x;

   dbms_output.put_line(l_requesttype);
end;

答案 1 :(得分:1)

不推荐使用EXTRACTVALUE功能。它仍然支持向后兼容性。但是,Oracle建议您使用XMLTABLE函数,或者使用XMLCAST和XMLQUERY函数。有关更多信息,请参阅XMLTABLE,XMLCAST和XMLQUERY,请参阅EXTRACTVALUE

功能xmltable运行正常,您也可以使用XMLQUERY

SELECT XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' 
   PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<VXIN>
<REQUESTS>
<REQUEST>
<REQUESTTYPE>ADD</REQUESTTYPE>
<REQUESTNUMBER>12345</REQUESTNUMBER>
<ID>1234567</ID>
<ACCESSLIST>
<ACCESS>
<ACCESSLEVEL>
<AID>123789</AID>
</ACCESSLEVEL>
<PERSONNEL>
<REQUESTEDFOR>
<UID>13579</UID>
<FIRSTNAME>MOBY</FIRSTNAME>
</REQUESTEDFOR>
</PERSONNEL>
</ACCESS>
</ACCESSLIST>
</REQUEST>
</REQUESTS>
</VXIN>') RETURNING CONTENT) AS REQUESTTYPE
FROM dual;

但是,如果您想要提取的不仅仅是一个值,XMLTABLE()应该更好。

答案 2 :(得分:0)

根据Wernfried发布的解决方案,我调整了一下查询,以便从我的表中读取值。以下是我的最终查询:

select XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' passing xmltype(XML_DATA) RETURNING CONTENT) AS REQUESTTYPE from table;