Oracle 提取几个 xpath 值
Oracle extract few xpath values
我正在尝试从此 xml
中提取三个 printerLocations
printerLocations 存储在 printer/printer-header/elem 下,属性名称为 printerLocations
问题是如何在列表中获取结果
像“美国,英国,(空)”
或者像我可以这样查询的列格式:
select * from ( this xml query) where column1 = "USA"
这是一个示例 xml:
<?xml version="1.0" encoding="UTF16" standalone="no" ?>
<printer>
<printer-header>
<elem name="printerId">XROX101-19341</elem>
<elem name="printerDate">05/11/19 12:27:48</elem>
<elem name="printerLocations">
<elem name="countryCd">USA</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd">UK</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd"/>
</elem>
</printer-header>
</printer>
我尝试了什么:
select XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"]/elem[@name="countryCd"]/text()').getStringVal() from printers
/
这只是美国的刺痛值
我希望得到的输出是一个 table 三列,
COUNTRY1 COUNTRY2 COUNTRY3
USA UK NULL
您可以使用 XMLTable 提取多个值,包括父元素值,例如:
select printerId, printerDate, countryCd
from xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype('<?xml version="1.0" encoding="UTF16" standalone="no" ?>
<printer>
<printer-header>
<elem name="printerId">XROX101-19341</elem>
<elem name="printerDate">05/11/19 12:27:48</elem>
<elem name="printerLocations">
<elem name="countryCd">USA</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd">UK</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd"/>
</elem>
</printer-header>
</printer>')
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
)
PRINTERID
PRINTERDATE
COUNTRYCD
XROX101-19341
05/11/19 12:27:48
USA
XROX101-19341
05/11/19 12:27:48
UK
XROX101-19341
05/11/19 12:27:48
null
您可以将 'printDate' 值转换为实际日期,假设它是固定格式。
无论哪种方式,您都可以将其用作内联视图或 CTE。
What I tried:
select XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"]/elem[@name="countryCd"]/text()').getStringVal() from printers
这会将所有国家/地区值作为一个字符串;使用 XMLTable 而不是单独获取每个值,并允许您轻松获取其他数据,以及一次获取多个 XML 文档的数据。
由于您的字符串来自 table,因此变为:
select x.printerId, x.printerDate, x.countryCd
from printers p
cross apply xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype(p.xml_string)
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
) x
PRINTERID
PRINTERDATE
COUNTRYCD
XROX101-19341
05/11/19 12:27:48
USA
XROX101-19341
05/11/19 12:27:48
UK
XROX101-19341
05/11/19 12:27:48
null
包裹在外部查询中,带有转换后的日期,如:
select * from (
select
printerId,
to_date(printerDate, 'DD/MM/RR HH24:MI:SS') as printerDate,
countryCd
from printers p
cross apply xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype(p.xml_string)
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
)
) x
where x.countryCd = 'USA'
PRINTERID
PRINTERDATE
COUNTRYCD
XROX101-19341
2019-11-05 12:27:48
USA
All I need is a table with three columns
你可以调整那个结果;但更简单的是,您可以使用类似的方法,按索引定位每个打印机位置:
select x.countryCd1, x.countryCd2, x.countryCd3
from printers p
cross apply xmltable(
'/printer/printer-header'
passing xmltype(p.xml_string)
columns
countryCd1 varchar2(3) path 'elem[@name="printerLocations"][1]/elem[@name="countryCd"]',
countryCd2 varchar2(3) path 'elem[@name="printerLocations"][2]/elem[@name="countryCd"]',
countryCd3 varchar2(3) path 'elem[@name="printerLocations"][3]/elem[@name="countryCd"]'
) x
COUNTRYCD1
COUNTRYCD2
COUNTRYCD3
USA
UK
null
您可以改为使用三个 XMLQuery 调用,但这会涉及更多的重复。
或者,如果您真的想要,您仍然可以使用原始提取物三次,并添加一个索引:
select
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][1]/elem[@name="countryCd"]/text()').getStringVal() as countryCd1,
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][2]/elem[@name="countryCd"]/text()').getStringVal() as countryCd2,
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][3]/elem[@name="countryCd"]/text()').getStringVal() as countryCd3
from printers
... gets the same result.
无论哪种方式,您都必须事先知道您期望最终结果中有多少个值(列)。 (否则你必须使用动态 SQL...)
我正在尝试从此 xml
中提取三个 printerLocations
printerLocations 存储在 printer/printer-header/elem 下,属性名称为 printerLocations
问题是如何在列表中获取结果
像“美国,英国,(空)”
或者像我可以这样查询的列格式:
select * from ( this xml query) where column1 = "USA"
这是一个示例 xml:
<?xml version="1.0" encoding="UTF16" standalone="no" ?>
<printer>
<printer-header>
<elem name="printerId">XROX101-19341</elem>
<elem name="printerDate">05/11/19 12:27:48</elem>
<elem name="printerLocations">
<elem name="countryCd">USA</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd">UK</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd"/>
</elem>
</printer-header>
</printer>
我尝试了什么:
select XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"]/elem[@name="countryCd"]/text()').getStringVal() from printers
/
这只是美国的刺痛值
我希望得到的输出是一个 table 三列,
COUNTRY1 COUNTRY2 COUNTRY3
USA UK NULL
您可以使用 XMLTable 提取多个值,包括父元素值,例如:
select printerId, printerDate, countryCd
from xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype('<?xml version="1.0" encoding="UTF16" standalone="no" ?>
<printer>
<printer-header>
<elem name="printerId">XROX101-19341</elem>
<elem name="printerDate">05/11/19 12:27:48</elem>
<elem name="printerLocations">
<elem name="countryCd">USA</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd">UK</elem>
</elem>
<elem name="printerLocations">
<elem name="countryCd"/>
</elem>
</printer-header>
</printer>')
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
)
PRINTERID | PRINTERDATE | COUNTRYCD |
---|---|---|
XROX101-19341 | 05/11/19 12:27:48 | USA |
XROX101-19341 | 05/11/19 12:27:48 | UK |
XROX101-19341 | 05/11/19 12:27:48 | null |
您可以将 'printDate' 值转换为实际日期,假设它是固定格式。
无论哪种方式,您都可以将其用作内联视图或 CTE。
What I tried: select XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"]/elem[@name="countryCd"]/text()').getStringVal() from printers
这会将所有国家/地区值作为一个字符串;使用 XMLTable 而不是单独获取每个值,并允许您轻松获取其他数据,以及一次获取多个 XML 文档的数据。
由于您的字符串来自 table,因此变为:
select x.printerId, x.printerDate, x.countryCd
from printers p
cross apply xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype(p.xml_string)
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
) x
PRINTERID | PRINTERDATE | COUNTRYCD |
---|---|---|
XROX101-19341 | 05/11/19 12:27:48 | USA |
XROX101-19341 | 05/11/19 12:27:48 | UK |
XROX101-19341 | 05/11/19 12:27:48 | null |
包裹在外部查询中,带有转换后的日期,如:
select * from (
select
printerId,
to_date(printerDate, 'DD/MM/RR HH24:MI:SS') as printerDate,
countryCd
from printers p
cross apply xmltable(
'/printer/printer-header/elem[@name="printerLocations"]'
passing xmltype(p.xml_string)
columns
printerId varchar2(30) path './../elem[@name="printerId"]',
printerDate varchar2(17) path './../elem[@name="printerDate"]',
countryCd varchar2(3) path 'elem[@name="countryCd"]'
)
) x
where x.countryCd = 'USA'
PRINTERID | PRINTERDATE | COUNTRYCD |
---|---|---|
XROX101-19341 | 2019-11-05 12:27:48 | USA |
All I need is a table with three columns
你可以调整那个结果;但更简单的是,您可以使用类似的方法,按索引定位每个打印机位置:
select x.countryCd1, x.countryCd2, x.countryCd3
from printers p
cross apply xmltable(
'/printer/printer-header'
passing xmltype(p.xml_string)
columns
countryCd1 varchar2(3) path 'elem[@name="printerLocations"][1]/elem[@name="countryCd"]',
countryCd2 varchar2(3) path 'elem[@name="printerLocations"][2]/elem[@name="countryCd"]',
countryCd3 varchar2(3) path 'elem[@name="printerLocations"][3]/elem[@name="countryCd"]'
) x
COUNTRYCD1 | COUNTRYCD2 | COUNTRYCD3 |
---|---|---|
USA | UK | null |
您可以改为使用三个 XMLQuery 调用,但这会涉及更多的重复。
或者,如果您真的想要,您仍然可以使用原始提取物三次,并添加一个索引:
select
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][1]/elem[@name="countryCd"]/text()').getStringVal() as countryCd1,
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][2]/elem[@name="countryCd"]/text()').getStringVal() as countryCd2,
XMLTYPE(xml_string).extract('/printer/printer-header/elem[@name="printerLocations"][3]/elem[@name="countryCd"]/text()').getStringVal() as countryCd3
from printers
... gets the same result.
无论哪种方式,您都必须事先知道您期望最终结果中有多少个值(列)。 (否则你必须使用动态 SQL...)