2010-09-28 20 views
6

Tôi cố gắng thêm không gian tên trên xml bằng cách sử dụng VỚI XMLNAMESPACES.Thêm không gian tên trên xml được tạo bởi truy vấn

Khi tôi thực hiện truy vấn của tôi, không gian tên được bổ sung phần tử gốc nhưng với phần tử thứ hai tôi có xmlns = "" cũng ... và tôi muốn loại bỏ ...

tôi cung cấp một ví dụ:

Queries để tạo các bảng và dữ liệu:

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 

tôi tạo ra xml với các truy vấn này:

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 tạo:

<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> 

Vì vậy, tôi cố gắng này là tốt:

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 tạo ra bây giờ là:

<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> 

Trả lời

5

Daniel, các xmlns="" trên <DataRows> phương tiện yếu tố , đặt không gian tên mặc định cho <DataRows> và tất cả các hậu duệ không có vùng tên.

Nói cách khác, nếu không có xmlns="", toàn bộ cây XML sẽ nằm trong không gian tên http://www.mynamespace.com. (Bởi vì các khai báo không gian tên được thừa hưởng, cho đến khi bị ghi đè.) Và đó có thể là những gì bạn muốn. Nhưng SQL Server cho rằng bạn chỉ muốn phần tử <Names> nằm trong không gian tên đó. Vì vậy, nó là "helpfully" loại bỏ không gian tên mặc định cho tất cả các phần tử con cháu.

Các giải pháp, sau đó, là để nói với SQL Server tất cả các yếu tố, không chỉ <Names>, phải ở trong không gian tên http://www.mynamespace.com.

(Nếu bạn hỏi tôi cách làm điều đó, câu trả lời là tôi không biết các tính năng XML của SQL Server. Nhưng có thể làm rõ điều gì đang xảy ra và những gì cần phải xảy ra sẽ giúp bạn tìm ra cách để nó xảy ra.)

cập nhật trong ánh sáng của truy vấn mới đăng và đầu ra:

@Daniel, sản lượng của bạn bây giờ là đúng về mặt kỹ thuật. Tất cả các phần tử đầu ra nằm trong không gian tên http://www.mynamespace.com. Các khai báo xmlns="http://www.mynamespace.com" trên các phần tử <Row> là không cần thiết ... chúng không thay đổi không gian tên của bất kỳ phần tử nào.

Bạn có thể không thích các khai báo bổ sung này, nhưng chúng không được tạo bất kỳ sự khác biệt nào đối với bất kỳ công cụ XML hạ lưu nào.

Nếu bạn muốn xóa chúng và nếu bạn không thể thực hiện điều đó bằng cách tinh chỉnh truy vấn SQL, bạn có thể chạy kết quả XML thông qua biểu định kiểu XSLT. Ngay cả một identity transformation có lẽ sẽ loại bỏ các khai báo không gian tên dư thừa, tôi tin.

+0

@Daniel, điều gì sẽ xảy ra nếu bạn đặt 'WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com')' trên SELECT ban đầu của bạn trong câu lệnh 'SET @XML = ...'?(cũng như nơi nó đã được) – LarsH

+0

Tôi đã cố gắng nhưng tôi không thể thiết lập VỚI VỚI XMLNAMESPACES trong một SET ... Một điều, thực sự mỗi khi có một SELECT, không gian tên được thiết lập bởi Sql Server. – Dan

+0

Vì vậy, tôi đã thay thế SET bằng một SELECT và tôi đặt WITH WITH XMLNAMESPACES ngay trước đây. Truy vấn được thực hiện ngay bây giờ nhưng chỉ cần đặt không gian tên với các phần tử "Hàng" ... – Dan

Các vấn đề liên quan