如何避免使用FOR XML PATH的子节点中的命名空间?

我想直接从数据库创建一个站点地图xml文件(包括图像),而无需其他进程(如转换或其他技巧)。

我的查询是:

;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

返回:

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

但是我需要这个输出,没有重复的名称空间声明:

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

我相信你会意识到额外的无意义的命名空间声明不会改变XML文档的含义,所以如果结果将被符合XML的工具所使用,它们应该没有关系。 不过,我知道有些工具不能正确执行XML名称空间,而在大型XML实例中,多余的重复名称空间声明可能会大大增加结果的大小,这可能会导致它自己的问题。

一般来说,没有解决这样的事实:在WITH XMLNAMESPACES前缀范围内的每个SELECT...FOR XML语句将在其结果集中的最外面的XML元素上生成名称空间声明,在所有支持XML的XML版本中SQL Server到SQL Server 2012。

在您的具体示例中,您可以通过分离SELECT而不是嵌套它们,并使用ROOT语法来封装根元素,从而非常接近所需的XML:

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 

结果是:

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

但是这种方法并不能提供一个完全一般的解决方案。


你可以使用UDF。 例:

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

结果:

<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>
链接地址: http://www.djcxy.com/p/11267.html

上一篇: How to avoid namespace in child nodes using FOR XML PATH?

下一篇: Javascript arrays, sorting, and branch predition