根据列表值的最大xpath提取xml标签

时间:2019-05-07 13:00:37

标签: sql oracle xpath

我正在尝试从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应该是什么的任何建议?

2 个答案:

答案 0 :(得分:0)

您的xpath在理论上对我来说很好 我不是专家,但是这里可能有问题:

您显示的MAX_INITIAL_VALUE的值为147129917,所以它已经四舍五入了吗? 因此,它不能等于XML对象中的实际值1.4712991655E8

也许有一个舍入函数:

currency varchar2(3) path 'ILA/PRODUCT_LIST/PRODUCT[INITIAL_VALUE=round(max(ILA/PRODUCT_LIST/PRODUCT/INITIAL_VALUE))]/MAP_ENTRY/CURRENCY_ENTRY'

如果存在的话,可能需要第二个参数将小数点后一位四舍五入

答案 1 :(得分:0)

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

或者,使用虚拟路径也可以解决问题,但这会降低查询速度。