2012-10-10 30 views
7

Tôi muốn tạo một tệp sơ đồ trang web xml (bao gồm hình ảnh) trực tiếp từ cơ sở dữ liệu mà không cần quy trình khác (như chuyển đổi hoặc thủ thuật khác).Làm thế nào để tránh không gian tên trong các nút con bằng cách sử dụng FOR XML PATH?

truy vấn của tôi là:

;WITH XMLNAMESPACES(
    DEFAULT 'http://www.sitemaps.org/schemas/sitemap/0.9', 
    'http://www.google.com/schemas/sitemap-image/1.1' as [image]) 
SELECT 
    (SELECT    
     'mysite' as [loc], 
     (select 
      'anotherloc' 
      as [image:loc] 
     for XML path('image:image'), type 
     ) 
    for xml path('url'), type 
) 
for xml path('urlset'), type 

Returns:

<urlset xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
    <url xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
    <loc>mysite</loc> 
    <image:image xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
     <image:loc>anotherloc</image:loc> 
    </image:image> 
    </url> 
</urlset> 

Nhưng tôi cần sản lượng này, mà không khai báo namespace lặp đi lặp lại:

<urlset xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
    <url> 
    <loc>mysite</loc> 
    <image:image> 
     <image:loc>anotherloc</image:loc> 
    </image:image> 
    </url> 
</urlset> 
+0

liên quan [trên DBA] (http://dba.stackexchange.com/questions/23624/how-to-remove-xmlns-from-child-elements -with-for-xml/23697 # 23697) –

+0

Bản sao có thể có của [Làm cách nào để xóa không gian tên dự phòng trong truy vấn lồng nhau khi sử dụng FOR XML PATH] (http://stackoverflow.com/questions/3242070/how-do-i- xóa-thừa-không gian tên-trong-lồng nhau-truy vấn-khi-sử dụng-cho-xml-path) – Gabrielius

Trả lời

2

tôi chắc chắn rằng bạn nhận ra rằng các khai báo không gian tên otiose bổ sung không thay đổi ý nghĩa của tài liệu XML, vì vậy nếu kết quả là b e được tiêu thụ bởi một công cụ tuân thủ XML, chúng không quan trọng. Tuy nhiên, tôi biết có một số công cụ không thực hiện đúng không gian tên XML và trong một trường hợp XML lớn, các khai báo không gian tên lặp lại thừa có thể làm tăng kích thước của kết quả một cách đáng kể, điều này có thể gây ra các vấn đề của riêng nó.

Nói chung, không có sự kiện nào xảy ra với mỗi mệnh đề SELECT...FOR XML trong phạm vi tiền tố WITH XMLNAMESPACES sẽ tạo khai báo không gian tên trên (các) phần tử XML ngoài cùng trong tập kết quả của nó, trong tất cả các phiên bản hỗ trợ XML của SQL Server lên đến SQL server 2012.

Trong ví dụ cụ thể của bạn, bạn có thể nhận được khá gần với XML mong muốn bằng cách tách SELECT s chứ không phải là làm tổ họ, và sử dụng cú pháp ROOT cho phần tử gốc bao bọc, như sau:

DECLARE @inner XML; 
WITH XMLNAMESPACES('http://www.google.com/schemas/sitemap-image/1.1' as [image]) 
SELECT @inner = 
( 
    SELECT  
     'anotherloc' AS [image:loc] 
    FOR XML PATH('image:image'), TYPE 
) 

;WITH XMLNAMESPACES( 
    DEFAULT 'http://www.sitemaps.org/schemas/sitemap/0.9' 
) 
SELECT    
     'mysite' AS [loc], 
     @inner 
FOR XML PATH('url'), ROOT('urlset'), TYPE 

Kết quả là:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
    <url> 
    <loc>mysite</loc> 
    <image:image xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns=""> 
     <image:loc>anotherloc</image:loc> 
    </image:image> 
    </url> 
</urlset> 

Nhưng cách tiếp cận này không cung cấp giải pháp hoàn toàn chung cho vấn đề.

1

Bạn có thể sử dụng UDF. Ví dụ:

ALTER FUNCTION [dbo].[udf_get_child_section] (
    @serviceHeaderId INT 
) 
RETURNS XML 



BEGIN 

    DECLARE @result XML; 

    SELECT @result = 
    (
     SELECT 1 AS 'ChildElement' 
     FOR XML PATH('Child') 
    ) 

    RETURN @result 

END 


GO 

DECLARE @Ids TABLE 
( 
    ID int 
) 

INSERT INTO @Ids 
SELECT 1 AS ID 
UNION ALL 
SELECT 2 AS ID 

;WITH XMLNAMESPACES (DEFAULT 'http://www...com/content') 
SELECT 
    [dbo].[udf_get_child_section](ID) 
FROM 
    @Ids 
FOR XML PATH('Parent') 

Kết quả:

<Parent xmlns="http://www...com/content"> 
    <Child xmlns=""> 
    <ChildElement>1</ChildElement> 
    </Child> 
</Parent> 
<Parent xmlns="http://www...com/content"> 
    <Child xmlns=""> 
    <ChildElement>1</ChildElement> 
    </Child> 
</Parent> 
Các vấn đề liên quan