извлечь тег xml на основе максимального значения xpath списка - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь извлечь значение валюты из списка 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

Первая строка должна включать USD. Любые предложения относительно того, каким должен быть xpath?

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Полный путь должен быть указан для функции 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    

В качестве альтернативы, игра с виртуальными путями также может помочь, но это замедлит ваш запрос.

0 голосов
/ 07 мая 2019

Ваш xpath выглядит хорошо для меня в теории, я не эксперт, но здесь может быть проблема:

ваше отображаемое значение MAX_INITIAL_VALUE равно 147129917, так что оно было округлено, верно?Следовательно, оно не может быть равно фактическому значению 1.4712991655E8 в вашем объекте XML

, возможно, если существует функция округления:

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

, вероятно, потребуется второй аргумент, для которого десятичная дробьокруглить, если оно существует

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...