首页 > 解决方案 > 根据列表值的最大 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 应该是什么的任何建议?

标签: sqloraclexpath

解决方案


必须为 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    

或者,使用虚拟路径也可以解决问题,但它会减慢您的查询速度。


推荐阅读