2010-09-28 74 views
6

我尝试使用WITH XMLNAMESPACES在xml上添加名称空间。在查询生成的xml中添加名称空间

当我执行我的查询,命名空间添加了根元素但我的xmlns第二个元素=“”还有......我想删除...

我提供一个例子:

查询用于创建表和数据:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[tblTest](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [nvarchar](30) NOT NULL, 
CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET IDENTITY_INSERT [dbo].[tblTest] ON 
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (1, N'Barack') 
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (2, N'Nicolas') 
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (3, N'Brian') 
SET IDENTITY_INSERT [dbo].[tblTest] OFF 

我生成与这些查询的XML:

DECLARE @Xml xml 
SET @Xml = (SELECT Id, Name 
      FROM dbo.tblTest 
      FOR XML PATH('Row'), ROOT('DataRows')); 

WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com') 
SELECT @Xml FOR XML PATH('Names'); 

的Xml生成:

<Names xmlns="http://www.mynamespace.com"> 
    <DataRows xmlns=""> 
    <Row> 
     <Id>1</Id> 
     <Name>Barak</Name> 
    </Row> 
    <Row> 
     <Id>2</Id> 
     <Name>Nicolas</Name> 
    </Row> 
    <Row> 
     <Id>3</Id> 
     <Name>Brian</Name> 
    </Row> 
    </DataRows> 
</Names> 

所以,我试试这个,以及:

DECLARE @Xml xml 

;WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com') 
SELECT @Xml = (SELECT Id, Name 
    FROM dbo.tblTest 
    FOR XML PATH('Row'), TYPE); 

;WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com') 
SELECT @Xml 
FOR XML PATH('DataRows'), ROOT('Names') 

生成的XML现在是:

<Names xmlns="http://www.mynamespace.com"> 
    <DataRows> 
    <Row xmlns="http://www.mynamespace.com"> 
     <Id>1</Id> 
     <Name>Barak</Name> 
    </Row> 
    <Row xmlns="http://www.mynamespace.com"> 
     <Id>2</Id> 
     <Name>Nicolas</Name> 
    </Row> 
    <Row xmlns="http://www.mynamespace.com"> 
     <Id>3</Id> 
     <Name>Brian</Name> 
    </Row> 
    </DataRows> 
</Names> 

回答

5

丹尼尔,在xmlns=""<DataRows>元件的装置,将<DataRows>的默认名称空间和所有后代设置为no namespace。

换句话说,如果xmlns=""都没有了,整个XML树将在http://www.mynamespace.com命名空间。 (因为命名空间声明是继承的,直到被覆盖。)这可能是你想要的。但SQL Server认为你只需要<Names>元素在该名称空间中。所以它“帮助”去除所有后代元素的默认命名空间。

的解决方案,那么,就是要告诉的SQL Server 所有的元素,而不仅仅是<Names>,应在http://www.mynamespace.com命名空间。 (如果你问我该怎么做,答案是我不知道SQL Server XML的功能,但也许澄清发生了什么,需要发生什么将帮助你找出如何实现它。 )

在新发布的查询和输出的光更新

@Daniel,你的输出是目前技术上是正确的。所有的输出元素都在http://www.mynamespace.com命名空间中。 <Row>元素上的xmlns="http://www.mynamespace.com"声明是多余的......它们不会更改任何元素的名称空间。

您可能不喜欢额外的声明,但它们不应该对任何下游XML工具有任何影响。

如果您想删除它们,并且如果您无法通过调整SQL查询来实现这一点,则可以通过XSLT样式表运行生成的XML。我相信,即使是identity transformation也可能会摆脱冗余的命名空间声明。

+0

@Daniel,如果你在'SET @XML = ...'声明的初始SELECT中放入'WITH XMLNAMESPACES(DEFAULT'http://www.mynamespace.com'),会发生什么?(以及它已经在哪里) – LarsH 2010-09-28 22:36:09

+0

我试过了,但我不能在SET中设置WITH XMLNAMESPACES ...另一件事,实际上每次有SELECT时,命名空间都由Sql Server设置。 – Dan 2010-09-29 15:26:48

+0

因此,我已经通过SELECT替换了SET,并且之前放置了WITH XMLNAMESPACES。该查询现在执行,但只是将名称空间与“行”元素... – Dan 2010-09-29 19:41:37