如何在 SQL Server 2019 中生成 XML 站点地图?

问题描述

我想从 sql Server 中生成站点地图,并使用以下产品表将其保存到我的系统驱动器:

示例数据

我尝试使用 FOR XML PATH 查询,但它没有给我正确的结果:

DECLARE @xml XML = (SELECT 
                        (SELECT 
                                '' AS "data()" 
                         FOR XML PATH ('loc'),TYPE),(SELECT 
                                '' AS "data()" 
                         FOR XML PATH ('changefreq'),(SELECT 
                                '' AS "data()" 
                         FOR XML PATH ('priority'),'' AS 'Name!1!ELEMENT' 
                    FROM dbo.product o 
                    FOR XML PATH ('url'),ROOT('dummytag'),TYPE)

-- Magic happens here!       

    SELECT 1 AS Tag,0 AS Parent,@xml AS [urlset!1!!xmltext],'http://www.sitemaps.org/schemas/sitemap/0.9' AS [urlset!1!xmlns],'http://www.sitemaps.org/schemas/sitemap/0.9' AS [urlset!1!xmlns:image]
    FOR XML EXPLICIT

模板 xml:

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

我想要的是这样的结果:

<?xml version="1.0" encoding="UTF-8"?>
<urlset
    xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    <url>
        <loc>https://www.example.com/product/dkp-4658551/%D9%85%D8%A7%D9%86%D8%AA%D9%88-%D8%B2%D9%86%D8%A7%D9%86%D9%87-27-%D9%85%D8%AF%D9%84-%DA%AF%D9%84-%D9%88-%D9%BE%D9%86%D8%AC%D8%B1%D9%87-%DA%A9%D8%AF-v78-%D8%B1%D9%86%DA%AF-%D8%B7%D9%88%D8%B3%DB%8C</loc>
        <changefreq>weekly</changefreq>
        <priority>0.8</priority>
        <image:image>
            <image:loc>https://example.com/mysite-products/3d1201f33f4e6dd6114ee6ec55be20fb5581f382_1615206830.jpg?x-oss-process=image/resize,m_lfit,h_350,w_350/quality,q_60</image:loc>
            <image:caption>مانتو زنانه 27 مدل گل و پنجره کد V78 رنگ طوسی</image:caption>
        </image:image>
    </url>
</urlset>

解决方法

因为没有提供 DDL 和样本数据群,所以我冒昧地创建了它。

通过使用 XQuery 及其 FLWOR 表达式,可以轻松创建站点地图 XML。

SQL

-- DDL and sample data population,start
DECLARE @tbl TABLE 
(
    ID INT IDENTITY PRIMARY KEY,loc VARCHAR(2048),changefreq VARCHAR(10),priority DECIMAL(2,1),image VARCHAR(2048),caption NVARCHAR(255)
);
INSERT INTO @tbl (loc,changefreq,priority,image,caption) VALUES
('https://example.com/product1','hourly',0.5,'https://example.com/asset/img1.jpg',N'caption1'),('https://example.com/product2','daily',0.2,'https://example.com/asset/img2.jpg',N'caption2');
-- DDL and sample data population,end

;WITH XMLNAMESPACES(DEFAULT 'http://www.sitemaps.org/schemas/sitemap/0.9','http://www.google.com/schemas/sitemap-image/1.1' AS [image])
SELECT (
    SELECT * 
    FROM @tbl
    FOR XML PATH('r'),TYPE,ROOT('root')
).query('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
{
    for $x in /root/r
    return <url>
        <loc>{data($x/loc)}</loc>
        <changefreq>{data($x/changefreq)}</changefreq>
        <priority>{data($x/priority)}</priority>
        <image:image>
            <image:loc>{data($x/image)}</image:loc>
            <image:caption>{data($x/caption)}</image:caption>
        </image:image>
    </url>
}
</urlset>');

输出

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
  <url>
    <loc>https://example.com/product1</loc>
    <changefreq>hourly</changefreq>
    <priority>0.5</priority>
    <image:image>
      <image:loc>https://example.com/asset/img1.jpg</image:loc>
      <image:caption>caption1</image:caption>
    </image:image>
  </url>
  <url>
    <loc>https://example.com/product2</loc>
    <changefreq>daily</changefreq>
    <priority>0.2</priority>
    <image:image>
      <image:loc>https://example.com/asset/img2.jpg</image:loc>
      <image:caption>caption2</image:caption>
    </image:image>
  </url>
</urlset>
,

以下也返回您需要的内容 - 对我来说似乎更简单。此外,如果您想添加版本和编码,我相信您可以做到的唯一方法是转换为字符串。

DECLARE @Xml XML = null,@XMLStr NVARCHAR(MAX) = '<?xml version="1.0" encoding="UTF-8"?>';

WITH XMLNAMESPACES (DEFAULT 'http://www.sitemaps.org/schemas/sitemap/0.9','http://www.google.com/schemas/sitemap-image/1.1' AS image)  
SELECT @Xml = (SELECT loc,[priority],[image] as [image:image/image:loc],[caption] as [image:image/image:caption]
FROM (
  VALUES ('https://example.com/product1','title1',10,0.1),20,0.2)
) P (loc,[image],caption,[priority])
FOR XML PATH ('url'),ROOT('urlset'));

SELECT @Xml;

-- Convert to a string and add the `version` + `encoding` tag.
SELECT @XMLStr + CAST(@XML AS NVARCHAR(MAX));

返回:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/product1</loc>
    <changefreq>10</changefreq>
    <priority>0.1</priority>
    <image:image>
      <image:loc>https://example.com/asset/img1.jpg</image:loc>
      <image:caption>title1</image:caption>
    </image:image>
  </url>
  <url>
    <loc>https://example.com/product2</loc>
    <changefreq>20</changefreq>
    <priority>0.2</priority>
    <image:image>
      <image:loc>https://example.com/asset/img2.jpg</image:loc>
      <image:caption>title1</image:caption>
    </image:image>
  </url>
</urlset>

注意:您没有提供更改频率和代表它的词之间的映射。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...