我想直接从数据库创建一个站点地图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>
答案 0 :(得分:3)
我确信您已经意识到额外的otiose名称空间声明不会改变XML文档的含义,因此如果结果将由符合XML的工具使用,则它们无关紧要。尽管如此,我知道有一些工具没有正确地执行XML命名空间,并且在大型XML实例中,多余的重复命名空间声明可能会大大增加结果的大小,这可能会导致其自身的问题。
通常情况下,SELECT...FOR XML
前缀范围内的每个WITH XMLNAMESPACES
语句都会在其结果集中最外层的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>
但是这种方法并没有为这个问题提供一个完全通用的解决方案。
答案 1 :(得分:1)
您可以使用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>
答案 2 :(得分:0)
也许来不及回答,但这是一个快速的解决方案。
`DECLARE @PageNumber Int = 1; DECLARE @siteMapXml XML ; ;WITH XMLNAMESPACES ( 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd' as "schemaLocation", 'http://www.w3.org/2001/XMLSchema-instance' as xsi, 'http://www.google.com/schemas/sitemap-image/1.1' as [image], DEFAULT 'http://www.sitemaps.org/schemas/sitemap/0.9' ) SELECT @siteMapXml = ( SELECT Slug loc, convert(varchar(300),[Image]) as [image:image/image:loc] , Convert(char(10), UpdatedOnUtc, 126) as lastmod, 'hourly' as changefreq, '0.5' as priority FROM Products(NOLOCK) WHERE Pagenumber = @PageNumber FOR XML PATH ('url'), ROOT ('urlset')) SELECT @siteMapXml = REPLACE(CAST(@siteMapXml AS NVARCHAR(MAX)), ' xmlns:schemaLocation=', ' xsi:schemaLocation=') SELECT @siteMapXml`