2012-10-10 11 views
7

Chcę utworzyć plik xml mapy witryny (w tym obrazy) bezpośrednio z bazy danych bez innego procesu (jak transformacja lub inna sztuczka).Jak uniknąć przestrzeni nazw w węzłach potomnych za pomocą FOR XML PATH?

Moje zapytanie brzmi:

;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 

Powroty:

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

ale muszę to wyjście, bez wielokrotnego deklaracji przestrzeni nazw:

<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

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

+0

Możliwy duplikat [Jak usunąć nadmiarowy obszar nazw w zapytaniu zagnieżdżonym przy użyciu FOR PATH XML] (http://stackoverflow.com/questions/3242070/how-do-i- remove-redundant-namespace-in-nested-query-when-using-for-xml-path) – Gabrielius

Odpowiedz

2

Jestem pewien, że zdajesz sobie sprawę, że dodatkowe otios deklaracje przestrzeni nazw nie zmieniają znaczenia dokumentu XML, więc jeśli wynik będzie b Zużyte przez narzędzie zgodne z XML, nie powinny mieć znaczenia. Niemniej jednak wiem, że istnieją pewne narzędzia, które nie prawidłowo obsługują Przestrzeń nazw XML, a w dużej instancji XML zbyteczne powtarzające się deklaracje przestrzeni nazw mogą znacznie zwiększyć rozmiar wyniku, co może spowodować problemy.

W ogóle nie ma poruszanie się po tym, że każda instrukcja SELECT...FOR XML w zakresie w WITH XMLNAMESPACES prefiksu wygeneruje deklaracji przestrzeni nazw na element (ów) XML peryferyjnych w jej wyniku, we wszystkich wersjach XML wsparcie SQL Server do SQL Server 2012.

w Twoim konkretnym przykładzie, można uzyskać dość blisko do żądanego XML przez oddzielenie SELECT s zamiast ich gniazdowania, a przy użyciu składni ROOT do otaczającej elementu głównego, a więc:

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 

Wynik:

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

Jednak to podejście nie zapewnia całkowicie ogólnego rozwiązania problemu.

1

Możesz użyć UDF. Przykład:

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

Wynik:

<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> 
Powiązane problemy