在命名空间返回 null 的 XML 中选择



我从 Web 服务接收一个 XML 文件,有时这个 XML 带有命名空间,有时没有。

当我在 @myDoc 变量中包含 XML 时,选择返回 null。但是,如果我删除"xmlns"部分,则选择通常会返回值。

我做错了什么?

DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
    <cStat>100</cStat>
</infProt>'
SET @CSTAT =  @myDoc.value('(/infProt/cStat)[1]', 'VARCHAR(MAX)' )
SELECT @CSTAT
您需要

使用 WITH XMLNAMESPACES 指定命名空间,并将别名归因于命名空间(我在这里使用了x(。请注意,您还需要将SET切换到SELECT才能使用它:

WITH XMLNAMESPACES ('some_namespace' as x)
SELECT @CSTAT =  @myDoc.value('(/x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' );

SqlFiddle 演示

编辑,回复:带/不带命名空间的动态

您可以使用与命名空间无关的函数local-name()绕过命名空间:

SELECT @CSTAT =  @myDoc.value(
      '(/*[local-name()="infProt"]/*[local-name()="cStat"])[1]', 'VARCHAR(MAX)');

更新的小提琴

使用

local-name() 时必须注意的是,这显然会检测路径中任何命名空间中具有相同名称的元素,除非您还使用 namespace-uri .

对于 value(( 方法在选择文本中声明命名空间

DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
    <cStat>100</cStat>
</infProt>'
select  @CSTAT =  @myDoc.value('declare namespace x="some_namespace"; ( /x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' )
select @CSTAT

最新更新