【问题标题】:Extracting value from xml data in Oracle从 Oracle 中的 xml 数据中提取值
【发布时间】:2017-05-05 19:03:21
【问题描述】:

我需要帮助来从存储在我的一个表列中的 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>

非常感谢任何帮助。

【问题讨论】:

  • 请显示您的预期输出,以及表模式定义。
  • 我认为这很明确。
  • 我正在寻找为上述 xml 返回“添加”的查询。我的表有上面的 xml 列和其他一些日期属性。

标签: xml oracle extract


【解决方案1】:

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

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

【讨论】:

  • XML_DATA的数据类型是什么?如果是XMLTYPE,则不必创建xmltype(XML_DATA),只需使用XML_DATA。如果数据类型是 VARCHAR2 或 CLOB,则需要 xmltype(XML_DATA)
  • 是的@Wernfried Domscheit,我表中的 XML_DATA 是 CLOB 数据类型
【解决方案2】:

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() 应该会更好。

【讨论】:

  • 感谢 Wernfried,上述解决方案完美运行!
【解决方案3】:

一种方法:

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;

【讨论】:

  • 感谢 Rene,上面的块有效!是否有单行查询可用于直接从表中读取 xml 数据并获得所需的输出。我问的原因是因为我必须对表中满足我的 where 子句的多个记录执行此操作。
  • 简单地替换xmltype(),resp。 l_xml 与您的列名。
猜你喜欢
  • 2014-01-19
  • 2015-11-21
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
  • 2022-07-21
相关资源
最近更新 更多