XMLTable 不会从 XML 中的子项获取数据
Posted
技术标签:
【中文标题】XMLTable 不会从 XML 中的子项获取数据【英文标题】:XMLTable doesn't get data from children in XML 【发布时间】:2018-04-27 12:15:13 【问题描述】:我有这块 XML 数据,我需要使用 XMLTable 来获取 bulletinWorkl:id
和 bulletinWork/outOfServices/outOfService/document:destinationName
。
<?xml version="1.0" encoding="ISO-8859-1"?>
<cern:bulletinWork id="5307cedc-2208-3701-9b9d-e69664b1ef31">
<cern:outOfServices>
<cern:outOfService id="e95d491b-2876-3e08-901f-b0f79be86bfb">
<cern:document destinationName="MonsA" type="S427"></cern:document>
</cern:outOfService>
<cern:outOfService id="fab04992-a33f-3a8c-ad16-29cd54fb93d6">
<cern:document destinationName="MonsB" type="S427"></cern:document>
</cern:outOfService>
</cern:outOfServices>
</cern:bulletinWork>
我正在尝试运行此查询并成功取回 bulletinWork
中的 ID 属性,但 bulletinWork/outOfServices/outOfService/document
中的 destinationName 为空。
select X.Id, X.DestinationName from S1589_XML_Bulletin, XMLTABLE(
'$d/*:bulletinWork'
PASSING XMLTYPE(XML_RAW) as "d"
COLUMNS
Id VARCHAR2(50) PATH '@*:id',
DestinationName VARCHAR2(50) PATH '*:outOfServices/*:outOfService/*:document/*:destinationName'
) AS X
有人看到我在这里做错了吗? 我需要得到:
Id DestinationName
------------------------------------- ------------------
5307cedc-2208-3701-9b9d-e69664b1ef31 MonsA
5307cedc-2208-3701-9b9d-e69664b1ef31 MonsB
【问题讨论】:
【参考方案1】: COLUMNS
Id VARCHAR2(50) PATH '@id',
DestinationName VARCHAR2(50) PATH 'string-join(distinct-values(*:outOfServices/*:outOfService/*:document/@destinationName),", ")'
您不必为无前缀属性使用命名空间。它们的命名空间被定义为父元素。
在示例 xml 中有多个 cern:outOfService
这就是我使用 string-join
和 distinct-values
的原因
更新:
1) 它更长,但对我来说更清晰。两个xml表的Join。
select * from xmltable('*:bulletinWork' passing xmltype('<cern:bulletinWork id="5307cedc-2208-3701-9b9d-e69664b1ef31" xmlns:cern="aaa">
<cern:outOfServices>
<cern:outOfService id="e95d491b-2876-3e08-901f-b0f79be86bfb">
<cern:document destinationName="MonsA" type="S427"></cern:document>
</cern:outOfService>
<cern:outOfService id="fab04992-a33f-3a8c-ad16-29cd54fb93d6">
<cern:document destinationName="MonsB" type="S427"></cern:document>
</cern:outOfService>
</cern:outOfServices>
</cern:bulletinWork>')
COLUMNS
Id VARCHAR2(50) PATH '@id',
outOfServices xmltype path '*:outOfServices'
) t1
,xmltable('*:outOfServices/*:outOfService' passing t1.outOfServices
COLUMNS DestinationName VARCHAR2(50) PATH '*:document/@destinationName')
2) 从子节点访问父节点。
select * from xmltable('*:bulletinWork/*:outOfServices/*:outOfService' passing xmltype('<cern:bulletinWork id="5307cedc-2208-3701-9b9d-e69664b1ef31" xmlns:cern="aaa">
<cern:outOfServices>
<cern:outOfService id="e95d491b-2876-3e08-901f-b0f79be86bfb">
<cern:document destinationName="MonsA" type="S427"></cern:document>
</cern:outOfService>
<cern:outOfService id="fab04992-a33f-3a8c-ad16-29cd54fb93d6">
<cern:document destinationName="MonsB" type="S427"></cern:document>
</cern:outOfService>
</cern:outOfServices>
</cern:bulletinWork>')
COLUMNS
Id VARCHAR2(50) PATH './../../@id',
DestinationName VARCHAR2(50) PATH '*:document/@destinationName'
)
【讨论】:
您的解决方案运行良好,谢谢。我只是稍微调整了这个问题,因为之后我可能需要所有的destinationNames 单独用于验证目的。有没有办法让我同时获得他们而不是加入他们?以上是关于XMLTable 不会从 XML 中的子项获取数据的主要内容,如果未能解决你的问题,请参考以下文章
Oracle PL/SQL 使用 XMLTABLE 解析 xml 中的嵌套对象
使用 XMLtable/Xpath 转换 XML Clob 并将其存储在数据库表中
为啥在加载到 XMLTABLE 时会跳过 XML 文档的第 40,000 个字符?
Oracle XMLTABLE - 如何从 XMLType 中删除节点?