带有命名空间的 Oracle XMLQuery

Oracle XMLQuery with namespace

我有一个带有 varchar 列的 Oracle Table。这一栏的内容是XML个字符串。 现在我尝试提取此列的标记属性的值。 在 XML 内容具有已定义的命名空间之前,这可以正常工作。

以下代码工作正常:

with testTable(xml_val) as (select xmltype('   
    <InstanceName>          
        <PromotionInstance>       
        <Cycle> 
            <Type>
                <TypeValue days="28"/>                      
                </Type>
            </Cycle>
        </PromotionInstance>
    </InstanceName>
    ') from dual)
select xmlcast(xmlquery('/InstanceName/PromotionInstance/Cycle/Type/TypeValue/@days' passing xml_val returning content) as number(2)) as days from testTable;

但此代码 returns 始终为“null”:

with testTable(xml_val) as (select xmltype('   
    <InstanceName xmlns="foobar">          
        <PromotionInstance>       
        <Cycle> 
            <Type>
                <TypeValue days="28"/>                      
                </Type>
            </Cycle>
        </PromotionInstance>
    </InstanceName>
    ') from dual)
select xmlcast(xmlquery('/InstanceName/PromotionInstance/Cycle/Type/TypeValue/@days' passing xml_val returning content) as number(2)) as days from testTable;

所以我试图找到解决方案。我发现,我必须在 XML 查询中声明命名空间。但是怎么办?

谢谢你的帮助。

您可以使用 XMLTABLE:

with testTable(xml_val) as (
select xmltype('   
    <InstanceName xmlns="foobar">          
        <PromotionInstance>       
        <Cycle> 
            <Type>
                <TypeValue days="28"/>                      
                </Type>
            </Cycle>
        </PromotionInstance>
    </InstanceName>
    ') from dual
)
select days
from   testTable t
       CROSS JOIN XMLTABLE(
           XMLNAMESPACES(DEFAULT 'foobar'),
           '/InstanceName/PromotionInstance/Cycle/Type/TypeValue'
           passing t.xml_val
           COLUMNS
             days NUMBER(2) PATH './@days'
       );

输出:

DAYS
28

db<>fiddle here

您可以声明一个默认命名空间:

select
  xmlcast(
    xmlquery(
      'declare default element namespace "foobar";
      /InstanceName/PromotionInstance/Cycle/Type/TypeValue/@days'
      passing xml_val
      returning content
    )
    as number(2)
  ) as days
from testTable;

或使用XML表格:

select x.days
from testTable t
cross apply xmltable (
  xmlnamespaces(default 'foobar'),
  '/InstanceName/PromotionInstance/Cycle/Type/TypeValue'
  passing t.xml_val
  columns days number(2) path '@days'
) x;

如果您想一次从 XML 中提取多个内容,哪个更灵活、更简单。

db<>fiddle