使用 plsql 解析带有子节点的 XML 格式

Parsing XML format with child nodes using plsql

我是 xml 格式和 sql 的新手,我有一个问题。我有一个 SQL 查询 returns xml 如下所示:

<?xml version="1.0" encoding="WINDOWS-1250"?>
<AROUND>
  <AB>
    <Connected>1</Connected>
    <EF>1010</EF>
    <GH>10162</GH>
    <IJ>HG-131120CXD</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>0</Connected>
    <EF>2123</EF>
    <GH>54321</GH>
    <IJ>HG-131120BRE</IJ>
    <KL>Old</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>1</Connected>
    <EF>4321</EF>
    <GH>12345</GH>
    <IJ>HG-131120DYX</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
</AROUND>

我必须从中提取 一些 值(例如:Connected、GH、IJ、KL)查询以便它的每个 A​​B 部分,无论它们有多少(在这个例子中有 3 个,但可能有 1-10 个甚至更多),都有自己的排。例如 (Connected, GH, IJ, KL),第一行将是:1 10162 HG-131120CXD New。等等等等...在此先感谢。

您可以使用XMLTable()从您的XML文档中提取您想要的数据;类似于:

select x.connected, x.gh, x.ij, x.kl
from your_query q
cross apply xmltable (
  '/AROUND/AB'
  passing q.xml_doc
  columns
    connected number path 'Connected',
    gh number path 'GH',
    ij varchar2(20) path 'IJ',
    kl varchar2(10) path 'KL'
) x

其中 your_query 是当前生成您的 XML 文档的任何查询。如果它生成一个字符串值,那么您可以将其包装在 XMLType() 中以进行转换。

db<>fiddle 显示两者,使用 CTE 表示您现有的查询以生成 XML 文档或字符串值,以获得:

CONNECTED |    GH | IJ           | KL 
--------: | ----: | :----------- | :--
        1 | 10162 | HG-131120CXD | New
        0 | 54321 | HG-131120BRE | Old
        1 | 12345 | HG-131120DYX | New

您可以像使用任何其他 SQL 一样在 PL/SQL 块中使用该 SQL 语句;如果 XML 文档在变量中,您可以执行以下操作:

for r in (
  select x.connected, x.gh, x.ij, x.kl
  from xmltable (
    '/AROUND/AB'
    passing l_xml_doc -- local XMLType variable
    columns
      connected number path 'Connected',
      gh number path 'GH',
      ij varchar2(20) path 'IJ',
      kl varchar2(10) path 'KL'
  ) x
) loop
  -- do something with r.connected, r.gh etc.
end loop;

您可以使用两个 XPath expressions with a Common Table Expressions。第一个拆分 AB 个节点,第二个将相关元素连接成一个字符串。

with tmp as (
select unnest (xpath ('//AB',
'<?xml version="1.0" encoding="WINDOWS-1250"?>
<AROUND>
  <AB>
    <Connected>1</Connected>
    <EF>1010</EF>
    <GH>10162</GH>
    <IJ>HG-131120CXD</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>0</Connected>
    <EF>2123</EF>
    <GH>54321</GH>
    <IJ>HG-131120BRE</IJ>
    <KL>Old</KL>
    <MN>284822</MN>
  </AB>
  <AB>
    <Connected>1</Connected>
    <EF>4321</EF>
    <GH>12345</GH>
    <IJ>HG-131120DYX</IJ>
    <KL>New</KL>
    <MN>284822</MN>
  </AB>
</AROUND>')) ab
)
select unnest (xpath ('concat(//Connected/text()," ",//GH/text()," ",//IJ/text()," ",//KL/text())', tmp.ab)) ab
from tmp;

这个returns:

            ab            
--------------------------
 1 10162 HG-131120CXD New
 0 54321 HG-131120BRE Old
 1 12345 HG-131120DYX New