如何在根元素上指定属性?

问题描述

短版

使用 sql Server FOR XML ROOT('Customers'),如何向该根节点添加属性

<Customers> ← attributes here
   <Customer>Ian</Customer>
   <Customer>Shelby</Customer>
   <Customer>Dave</Customer>
</Customers>

长版

sql Server 中使用 FOR XML 时:

SELECT *
FROM (VALUES
    (122,'All-Purpose Bike Stand'),(119,'Bike Wash'),(115,'Cable Lock')
) AS Products(ProductModelID,Name)
FOR XML PATH('Product')

它通常只返回元素:

<Product>
  <ProductModelID>122</ProductModelID>
  <Name>All-Purpose Bike Stand</Name>
</Product>
<Product>
  <ProductModelID>119</ProductModelID>
  <Name>Bike Wash</Name>
</Product>
<Product>
  <ProductModelID>115</ProductModelID>
  <Name>Cable Lock</Name>
</Product>

(3 rows affected)

那不是有效的 XML 文档,因为有 三个 顶级节点 - 而不仅仅是一个

这可以通过指定 ROOT('RootNodeName')解决

SELECT *
FROM (VALUES
    (122,Name)
FOR XML PATH('Product'),ROOT('Products')

<Products>
  <Product>
    <ProductModelID>122</ProductModelID>
    <Name>All-Purpose Bike Stand</Name>
  </Product>
  <Product>
    <ProductModelID>119</ProductModelID>
    <Name>Bike Wash</Name>
  </Product>
  <Product>
    <ProductModelID>115</ProductModelID>
    <Name>Cable Lock</Name>
  </Product>
</Products>

(3 rows affected)

优秀。

属性除外

以上内容很棒,但我还没有完成需要生成的 XML 文档。我需要向根节点添加一些属性

<Products operationalMode="Test" batchDate="2021-02-15T17:36:22" formatId="8e884ace-bee4-11e4-8dfc-aa07a5b093db">
  <Product>
    <ProductModelID>122</ProductModelID>
    <Name>All-Purpose Bike Stand</Name>
  </Product>
  <Product>
    <ProductModelID>119</ProductModelID>
    <Name>Bike Wash</Name>
  </Product>
  <Product>
    <ProductModelID>115</ProductModelID>
    <Name>Cable Lock</Name>
  </Product>
</Products>

如何向 XML ROOT('rootNode') 元素添加属性

解决方法

请尝试以下解决方案。

XML 至少应该格式良好。为了有效,它需要一个 XML 架构。

不清楚属性的来源是什么,所以我只是硬编码了它们的值。

如您所见,我们需要应用 FOR XML PATH 子句两次。一次用于“内部”XML。第二次用于根元素,并通过带有 at 符号的别名指定属性。

SQL

SELECT 'Test'AS [@operationalMode],'2021-02-15T17:36:22' AS [@batchDate],'8e884ace-bee4-11e4-8dfc-aa07a5b093db' AS [@formatId],(
    SELECT *
    FROM (VALUES
        (122,'All-Purpose Bike Stand'),(119,'Bike Wash'),(115,'Cable Lock')) AS Products(ProductModelID,Name)
    FOR XML PATH('Product'),TYPE
)
FOR XML PATH('Products'),TYPE;

输出

<Products operationalMode="Test" batchDate="2021-02-15T17:36:22" formatId="8e884ace-bee4-11e4-8dfc-aa07a5b093db">
  <Product>
    <ProductModelID>122</ProductModelID>
    <Name>All-Purpose Bike Stand</Name>
  </Product>
  <Product>
    <ProductModelID>119</ProductModelID>
    <Name>Bike Wash</Name>
  </Product>
  <Product>
    <ProductModelID>115</ProductModelID>
    <Name>Cable Lock</Name>
  </Product>
</Products>