Oracle,XMLTABLE,从标签获取值,如果标签接近等于

Oracle, XMLTABLE, get value from tag, if tag near equals

我有这个 XML 和表达式来获取值:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_1</date-type>
         <date-value>2020-01-01</date-value>
       </other-date>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1       PATH 'other-dates/other-date[1]/date-value',
        date_2       PATH 'other-dates/other-date[2]/date-value'
);

问题开始了,其中第一个值可能为空,因此一个标签消失了:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1          PATH 'other-dates/other-date[1]/date-value',
        date_2          PATH 'other-dates/other-date[2]/date-value'
);

在这种情况下 date_1 包含来自标签 date-type = "DATE_2" 的日期 这是错误的。

有没有办法说“如果日期类型="DATE_1"从日期值中获取值??

编辑:这个 xml 是更大 xml 的一部分,合同日期只是其中一个子标签

寻找子元素值而不是位置:

date_1       PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
date_2       PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'

修改了您的示例:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_1</date-type>
         <date-value>2020-01-01</date-value>
       </other-date>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1       PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
        date_2       PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'
);

DATE_1                         DATE_2                        
------------------------------ ------------------------------
2020-01-01                     2020-03-30                    

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1          PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
        date_2          PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'
);

DATE_1                         DATE_2                        
------------------------------ ------------------------------
                               2020-03-30                    

顺便说一句,您可以指定结果列的数据类型,这可以使它们更容易处理;由于这些值采用敏感格式,您可以在此处直接将它们声明为日期:

date_1 date PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
date_2 date PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'