根据属性值从 XML 中提取不同的值
Extract distinct values from XML based on attribute value
我需要从 XML 中提取到 doc_num
和 x
for kod = 'N'
,像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<main doc_num=99>
<item name="A">
<Dok Kod="N" X="1" Id="5"/>
<Dok Kod="N" X="4" Id="5"/>
</item>
<item name="B">
<Dok Kod="N" X="1" Id="2"/>
<Dok Kod="N" X="4" Id="6"/>
<Dok Kod="N" X="5" Id="8"/>
<Dok Kod="Z" X="4553" Id="8"/>
</item>
</main>
输出应该是这样的,我只需要不同的:
doc_num X
99 1
99 4
99 5
您可以将 XMLTable 与以 Kod=N
节点为目标的 Xpath 一起使用,然后沿着树返回以获取 doc_num
;此版本假定您的原始值为字符串:
select distinct xml.doc_num, xml.x
from your_table t
cross apply xmltable (
'/main/item/Dok[@Kod="N"]'
passing xmltype(t.your_xml)
columns doc_num number path './../../@doc_num',
x number path '@X'
) xml
DOC_NUM X
------- -
99 1
99 4
99 5
如果您的原始值已经是 XMLType,那么返回树上将不会按预期工作 - 不确定这是否是错误,但至少在 11gR2 和 18c 中似乎会发生。您可以通过转换为字符串并返回来解决此问题:
select distinct xml.doc_num, xml.x
from your_table t
cross apply xmltable (
'/main/item/Dok[@Kod="N"]'
passing xmltype(t.your_xml.getclobval())
columns doc_num number path './../../@doc_num',
x number path '@X'
) xml
DOC_NUM X
------- -
99 1
99 4
99 5
我刚刚注意到您为 Oracle 11g 标记了这个...因此交叉应用不可用,并且返回树上也不起作用;也不过滤子属性名称。因此,您可以使用两级 XMLTable 来执行此操作:
select distinct xml1.doc_num, xml2.x
from your_table t
cross join xmltable (
'/main'
passing xmltype(t.your_xml)
columns doc_num number path '@doc_num',
doks xmltype path 'item/Dok'
) xml1
cross join xmltable (
'/Dok'
passing xml1.doks
columns kod varchar2(1) path '@Kod',
x number path '@X'
) xml2
where xml2.kod = 'N'
DOC_NUM X
------- -
99 1
99 4
99 5
适用于 11g with a string or with an XMLType 来源。
我需要从 XML 中提取到 doc_num
和 x
for kod = 'N'
,像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<main doc_num=99>
<item name="A">
<Dok Kod="N" X="1" Id="5"/>
<Dok Kod="N" X="4" Id="5"/>
</item>
<item name="B">
<Dok Kod="N" X="1" Id="2"/>
<Dok Kod="N" X="4" Id="6"/>
<Dok Kod="N" X="5" Id="8"/>
<Dok Kod="Z" X="4553" Id="8"/>
</item>
</main>
输出应该是这样的,我只需要不同的:
doc_num X
99 1
99 4
99 5
您可以将 XMLTable 与以 Kod=N
节点为目标的 Xpath 一起使用,然后沿着树返回以获取 doc_num
;此版本假定您的原始值为字符串:
select distinct xml.doc_num, xml.x
from your_table t
cross apply xmltable (
'/main/item/Dok[@Kod="N"]'
passing xmltype(t.your_xml)
columns doc_num number path './../../@doc_num',
x number path '@X'
) xml
DOC_NUM X
------- -
99 1
99 4
99 5
如果您的原始值已经是 XMLType,那么返回树上将不会按预期工作 - 不确定这是否是错误,但至少在 11gR2 和 18c 中似乎会发生。您可以通过转换为字符串并返回来解决此问题:
select distinct xml.doc_num, xml.x
from your_table t
cross apply xmltable (
'/main/item/Dok[@Kod="N"]'
passing xmltype(t.your_xml.getclobval())
columns doc_num number path './../../@doc_num',
x number path '@X'
) xml
DOC_NUM X
------- -
99 1
99 4
99 5
我刚刚注意到您为 Oracle 11g 标记了这个...因此交叉应用不可用,并且返回树上也不起作用;也不过滤子属性名称。因此,您可以使用两级 XMLTable 来执行此操作:
select distinct xml1.doc_num, xml2.x
from your_table t
cross join xmltable (
'/main'
passing xmltype(t.your_xml)
columns doc_num number path '@doc_num',
doks xmltype path 'item/Dok'
) xml1
cross join xmltable (
'/Dok'
passing xml1.doks
columns kod varchar2(1) path '@Kod',
x number path '@X'
) xml2
where xml2.kod = 'N'
DOC_NUM X
------- -
99 1
99 4
99 5
适用于 11g with a string or with an XMLType 来源。