5

举个简单的例子:

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() 方法调用中的declare语句,或with 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" />

这篇 Technet 文章中,B. 声明默认命名空间部分显示了我想要实现的目标,但我得到了D. 使用默认命名空间的构造中显示的结果。由于我的示例看起来不太像后者,因此我不明白为什么要获得这些前缀。

更新:为了完整起见,这给出了与 with xmlnamespaces语法 完全相同的症状:

select t.c.query('.')
from @myXml.nodes('declare default element namespace "urn:somename";/root/line') t(c)
4

1 回答 1

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)

=>

<line xmlns="urn:somename" id="1" />
<line xmlns="urn:somename" id="2" />
<line xmlns="urn:somename" id="3" />
于 2013-10-29T15:33:59.053 回答