举个简单的例子:
declare @myXml xml
set @myXML = '
<root>
<line id="1"/>
<line id="2"/>
<line id="3"/>
</root>'
select t.c.query('.')
from @myXml.nodes('/root/line') t(c)
正如预期的那样,我回到了三行,看起来像这样:
<line id="1" />
但是,当XML声明其命名空间(即使只是默认的xmlns)时,您还需要在SQL中指定该命名空间,否则结果集将为空。我知道两种方法:在nodes()方法调用中使用声明语句,或者使用xmlnamespaces 语句使用。让我们使用后者:
declare @myXml xml
set @myXML = '
<root xmlns="urn:somename">
<line id="1"/>
<line id="2"/>
<line id="3"/>
</root>';
with xmlnamespaces(default 'urn:somename')
select t.c.query('.')
from @myXml.nodes('/root/line') t(c)
虽然我现在得到了结果,但结果确实有些奇怪。指定的命名空间将添加为“p1”而不是默认值。所以我的输出看起来像这样:
<p1:line xmlns:p1="urn:somename" id="1" />
在this Technet article中, B部分。声明默认命名空间显示我正在尝试实现的内容,但我得到 D中显示的结果。使用默认命名空间构建。由于我的例子看起来不像后者,我不明白为什么我会得到这些前缀。
更新 为了完整起见,这提供了与 with xmlnamespaces 语法完全相同的症状:
select t.c.query('.')
from @myXml.nodes('declare default element namespace "urn:somename";/root/line') t(c)
答案 0 :(得分:4)
当您最初查询XML时,在select
中声明默认元素名称空间,并且所有元素都将使用默认名称空间声明而不是前缀:
declare @myXml xml
set @myXML = '
<root xmlns="urn:somename">
<line id="1"/>
<line id="2"/>
<line id="3"/>
</root>';
with xmlnamespaces(default 'urn:somename')
select t.c.query('
declare default element namespace "urn:somename";
.')
from @myXml.nodes('/root/line') t(c)
=&GT;
<line xmlns="urn:somename" id="1" />
<line xmlns="urn:somename" id="2" />
<line xmlns="urn:somename" id="3" />