【发布时间】:2013-10-28 14:20:35
【问题描述】:
举个简单的例子:
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" />
在this Technet article 中,B 部分。声明默认命名空间 显示了我想要实现的目标,但我得到了 D 中显示的结果。使用默认命名空间构建。由于我的示例看起来不太像后者,所以我不明白为什么我会得到这些前缀。
更新: 为了完整起见,这给出了与 with xmlnamespaces 语法完全相同的症状:
select t.c.query('.')
from @myXml.nodes('declare default element namespace "urn:somename";/root/line') t(c)
【问题讨论】:
-
我认为您需要在 XQuery 语句中声明默认元素名称空间,正如文章 B 中所建议的那样。
-
@wst 无论我使用 xmlnamespaces 语法还是 declare 语句,我都会得到完全相同的症状。
-
您是否尝试在
select语句中声明默认命名空间? -
@wst 在 select 语句中?我不知道你的意思是什么。我已经尝试了上面显示的“with xmlnamespaces”语法并在 nodes() 调用中添加了声明,并且两者提供了相同的结果。
-
从“这段XML包含什么数据”的角度来看,
<p1:line xmlns:p1="urn:somename" id="1" />和<p1 id="1" />在urn:somename的默认命名空间内包含完全相同相同的数据.担心确切的字符串格式通常是其他地方脆弱的标志(例如使用手动解析而不是使用适当的 XML 库的其他一些代码)
标签: sql sql-server xml xquery xquery-sql