带有命名空间的 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 中提取多个内容,哪个更灵活、更简单。
我有一个带有 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 中提取多个内容,哪个更灵活、更简单。