SQL - 空白默认命名空间

时间:2012-05-07 22:13:50

标签: sql xml sql-server-2008 xquery

我有一个关系,它有一个XML列,用于存储以下结构中的数据

<Report id="b5d9b8da-7af4-4257-b825-b28af91dd833">
    <CreatedDate>04-12-2012</CreatedDate>
    <LastUpdated>04-12-2012</LastUpdated>
    <Reference>abc123</Reference>
</Report>

我正在编写一个存储过程来检索所有报告并将它们连接起来并将它们包装在名为reports的根节点中。到目前为止,我有以下内容;

WITH XMLNAMESPACES(DEFAULT 'http://www.defaultnamespace.com/1.0')
        SELECT
    @Xml = 
    (

            SELECT
                (
                    SELECT xml.query('.')
                    FROM
                        [database].[Reports]
                    WHERE
                        ClientId = @clientId
                    FOR XML PATH(''),
                    TYPE
                )
            FOR XML PATH('Reports'),
            TYPE
        )

虽然这会以正确的格式返回所有报告,但报告元素上存在一个空白的默认命名空间,如下所示;

<Reports xmlns="http://www.defaultnamespace.com/1.0">
<Report  xmlns="" id="b5d9b8da-7af4-4257-b825-b28af91dd833">
    <CreatedDate>04-12-2012</CreatedDate>
    <LastUpdated>04-12-2012</LastUpdated>
    <Reference>abc123</Reference>
</Report>
</Reports>

有人可以解释一种在报表元素上排除名称空间的合适方法吗?

任何帮助都非常感谢大家:)

2 个答案:

答案 0 :(得分:0)

您的问题是该列未存储默认命名空间“http://www.defaultnamespace.com/1.0”。

因此,您的代码的逻辑名称为NS =“”,name = Report。

SQL Server绝对正确。

你想做的是说

  顺便说一下,我存储的XML数据,我希望您将每个名称中逻辑上附加到每个名称的命名空间中的每个标记重写为“http://www.defaultnamespace”中相同相对名称的标记。 com / 1.0“命名空间,然后将其设为默认命名空间

AFAIK,你不能那样做(但如果你找到方法让我知道!)。您可以获得的最接近的是将其转换为nvarchar(max)而没有命名空间,然后再次使用所需的命名空间将其强制转换回来。

答案 1 :(得分:0)

这有点混乱,可能效率不高,但是您可以在中间XML上使用XQuery重新定义名称空间。

例如,您无需使用SQL Server的WITH XMLNAMESPACES在XQuery中声明默认名称空间,

if object_id(N'Reports') is not null drop table [Reports];
go
create table [Reports] (
    [ClientId] int not null,
    [xml] [xml] not null
)
go
insert [Reports] ([ClientID], [xml])
    values (1, N'<Report id="b5d9b8da-7af4-4257-b825-b28af91dd833">
    <CreatedDate>04-12-2012</CreatedDate>
    <LastUpdated>04-12-2012</LastUpdated>
    <Reference>abc123</Reference>
</Report>');
go
declare @clientId int = 1
select  (
    select [xml].query('/*:Report')
    from [Reports]
    where ClientId = @clientId
    for xml path('Reports'), type
    ).query('declare default element namespace "http://www.defaultnamespace.com/1.0";
    for $x in /*:Reports return
        <Reports>
        {
            for $y in $x/*:Report return
            <Report>
                {attribute id {$y/@id}}
                {element CreatedDate {$y/*:CreatedDate/text()}}
                {element LastUpdated {$y/*:LastUpdated/text()}}
                {element Reference {$y/*:Reference/text()}}
            </Report>
        }
        </Reports>')
go

这将返回以下XML块:

<Reports xmlns="http://www.defaultnamespace.com/1.0">
  <Report id="b5d9b8da-7af4-4257-b825-b28af91dd833">
    <CreatedDate>04-12-2012</CreatedDate>
    <LastUpdated>04-12-2012</LastUpdated>
    <Reference>abc123</Reference>
  </Report>
</Reports>