指定default时,SQL Server会创建XML命名空间

Cob*_*ger 5 xml sql sql-server xquery xquery-sql

举个简单的例子:

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)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,我回到了三行,看起来像这样:

<line id="1" />
Run Code Online (Sandbox Code Playgroud)

但是,当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)
Run Code Online (Sandbox Code Playgroud)

虽然我现在得到了结果,但结果却有一定的怪异.指定的命名空间将添加为"p1"而不是默认值.所以我的输出看起来像这样:

<p1:line xmlns:p1="urn:somename" id="1" />
Run Code Online (Sandbox Code Playgroud)

这篇Technet文章中,B部分声明一个默认命名空间显示了我正在尝试实现的内容,但是我使用默认命名空间得到了D. Construction中显示的结果.由于我的例子看起来不像后者,我不明白为什么我会得到这些前缀.

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

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

wst*_*wst 4

select在最初查询 XML 时声明默认元素命名空间,所有元素都将使用默认命名空间声明而不是前缀:

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)
Run Code Online (Sandbox Code Playgroud)

=>

<line xmlns="urn:somename" id="1" />
<line xmlns="urn:somename" id="2" />
<line xmlns="urn:somename" id="3" />
Run Code Online (Sandbox Code Playgroud)