sql - 根据列表值的最大 xpath 提取 xml 标签
问题描述
我正在尝试从 xml 列表中提取货币值,该值与另一个标签的最大值(在同一列表中)处于同一级别。
我正在使用 Oracle SQL 11gR2。最大值提取基于 xpath max() 函数。然后,我尝试根据 max() 的结果为列表下标(用于货币标签),但货币显示为 NULL。这是数据的一个小样本,并且使用了相关的 xpath:
with xml_data as (
select xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
<SOME_OBJECT xmlns="http://www.example.com/xxyy/">
<ILA>
<PRODUCT_LIST>
<PRODUCT>
<MAP_ENTRY>
<CURRENCY_ENTRY>EUR</CURRENCY_ENTRY>
</MAP_ENTRY>
<INITIAL_VALUE>1.4219777502E8</INITIAL_VALUE>
</PRODUCT>
<PRODUCT>
<MAP_ENTRY>
<CURRENCY_ENTRY>ZAR</CURRENCY_ENTRY>
</MAP_ENTRY>
<INITIAL_VALUE>1.4612991655E8</INITIAL_VALUE>
</PRODUCT>
<PRODUCT>
<MAP_ENTRY>
<CURRENCY_ENTRY>USD</CURRENCY_ENTRY>
</MAP_ENTRY>
<INITIAL_VALUE>1.4712991655E8</INITIAL_VALUE>
</PRODUCT>
</PRODUCT_LIST>
</ILA>
</SOME_OBJECT>') as msg from dual union all
select xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
<SOME_OBJECT xmlns="http://www.example.com/xxyy/">
<ILA>
<SUBSEQUENT_VALUE>10266</SUBSEQUENT_VALUE>
</ILA>
</SOME_OBJECT>') as msg from dual
)
--
select x.subsequent_value, x.max_initial_value ,x.currency
from xml_data d
,xmltable (xmlnamespaces(default 'http://www.example.com/xxyy/')
,'/SOME_OBJECT' passing d.msg
columns
max_initial_value number path 'max(ILA/PRODUCT_LIST/PRODUCT/INITIAL_VALUE)'
,currency varchar2(3) path 'ILA/PRODUCT_LIST/PRODUCT[INITIAL_VALUE=max(ILA/PRODUCT_LIST/PRODUCT/INITIAL_VALUE)]/MAP_ENTRY/CURRENCY_ENTRY'
,subsequent_value number path 'ILA/SUBSEQUENT_VALUE'
) as x;
所以现有的输出是:
SQL> @get_max
SUBSEQUENT_VALUE MAX_INITIAL_VALUE CUR
---------------- ----------------- ---
147129917
10266
第一行应包括美元。关于 xpath 应该是什么的任何建议?
解决方案
必须为 max() 函数指定完整路径,如下所示:
ILA/TION/PAWS/PRODUCT_LIST/PRODUCT[INITIAL_VALUE = max(/SOME_OBJECT/ILA/TION/PAWS/PRODUCT_LIST/PRODUCT/INITIAL_VALUE)]/MAP_ENTRY/CURRENCY_ENTRY'
使用原始帖子中的相同数据,并使用包含完整路径的修改后的 SQL 语句来显示货币:
select x.subsequent_value, x.max_initial_value ,x.currency
from xml_data d
,xmltable (xmlnamespaces(default 'http://www.example.com/xxyy/')
,'/SOME_OBJECT' passing d.msg
columns
p XMLTYPE PATH '.'
, max_initial_value number path 'max(ILA/TION/PAWS/PRODUCT_LIST/PRODUCT/INITIAL_VALUE)'
, currency varchar2(3) path 'ILA/TION/PAWS/PRODUCT_LIST/PRODUCT[INITIAL_VALUE = max(/SOME_OBJECT/ILA/TION/PAWS/PRODUCT_LIST/PRODUCT/INITIAL_VALUE)]/MAP_ENTRY/CURRENCY_ENTRY'
, subsequent_value number path 'ILA/TION/PAWS/SUBSEQUENT_VALUE'
) as x;
SUBSEQUENT_VALUE MAX_INITIAL_VALUE CURRENCY
---------------- ----------------- --------
147129917 USD
10266
或者,使用虚拟路径也可以解决问题,但它会减慢您的查询速度。
推荐阅读
- angular - 如何将类添加到 Angular 的 ngFor 中间元素或默认类
- reactjs - 反应:未捕获的类型错误:无法读取未定义的属性“应用程序”
- react-native - 如何制作反应原生甲板动画?
- java - Hadoop:如何通过现代 API(2.7+)启用中间数据压缩?
- javascript - onclick 事件未触发且下拉代码不起作用
- r - 加载内置数据时出现knitr错误
- node.js - 在通过云函数在 Firestore 中进行更改后从文档中检索对象数组
- javascript - 在我的练习中显示错误?“属性值后出现意外字符”
- python - UnicodeDecodeError:数据问题的意外结束
- jquery - Jquery - 在提交之前添加值