从 SQL 查询生成特定格式的 XML

Generating XML in specific format from SQL query

我需要根据 table

生成 XML
    DECLARE @tempXML AS TABLE
    (
        ID INT IDENTITY(1,1),
        Field VARCHAR(10),
        VALUE VARCHAR(20),
        LEVEL INT
    )

    INSERT INTO @tempXML
    VALUES
        ('FirstName','FN',2),
        ('LastName','LN',2),
        ('Address','testaddress',1),
        ('City','testcity',1)

XML格式如下图

<XmlFormat version="1.0">
  <address>
    <field id="Address">testaddress</field>
    <field id="City">testcity</field>   
    <borrower>
      <field id="FirstName">FN</field>
      <field id="LastName">LN</field>      
    </borrower>
  </address>
</XmlFormat>

我尝试了以下查询,但没有得到所需的 xml 格式的输出

SELECT 
    field AS 'field/@id',   
    value AS 'field/value'
    FROM @tempXML
    FOR     
    XML PATH('borrower'), ELEMENTS, ROOT('address')

输出是

<address>
  <borrower>
    <field id="FirstName">
      <value>FN</value>
    </field>
  </borrower>
  <borrower>
    <field id="LastName">
      <value>LN</value>
    </field>
  </borrower>
  <borrower>
    <field id="Address">
      <value>testaddress</value>
    </field>
  </borrower>
  <borrower>
    <field id="City">
      <value>testcity</value>
    </field>
  </borrower>
</address>

我的主要问题是处理级别值(table 级别列中的 1 和 2)并以 XML 所需的格式显示。如果 table 中还有级别值为 1 和 2 的任何其他条目,也应进行处理。(例如:('street','teststreet',1) 或 ('MidName','MN',2) 应该出现在 XML).

的正确部分

请帮忙

一个解决方案是为每个“级别”使用子查询。 此示例假设您的 table 不包含两个不同的地址,因为我还没有找到对您的属性进行分组的方法。

SELECT 
    (
        SELECT 
            field AS 'field/@id',   
            value AS 'field'
        FROM @tempXML
        WHERE LEVEL = 1
        FOR XML PATH(''), TYPE
    )
    ,(
        SELECT 
            field AS 'field/@id',   
            value AS 'field'
        FROM @tempXML
        WHERE LEVEL = 2
        FOR XML PATH(''), Root('borrower'), TYPE        
    )
    FOR XML PATH(''), Root('address'), TYPE

请尝试以下解决方案。

它正在使用 XQuery 及其 FLWOR 表达式。

简单易行,几乎是视觉制作 XML 过程,无需猜测。

所需的输出 XML 由两步组成:

  1. 通过 FOR XML PATH('r'), TYPE, ROOT('root')
  2. 创建原始 XML
  3. 通过 FLWOR 表达式编写 fine-tuned 最终 XML。

SQL

-- DDL and sample data population, start
DECLARE @tbl AS TABLE
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Field VARCHAR(10),
    VALUE VARCHAR(20),
    LEVEL INT
);
INSERT INTO @tbl VALUES
    ('FirstName','FN',2),
    ('LastName','LN',2),
    ('Address','testaddress',1),
    ('City','testcity',1);
-- DDL and sample data population, end

SELECT (
    SELECT * FROM @tbl
    FOR XML PATH('r'), TYPE, ROOT('root')
).query('<XmlFormat version="1.0">
    <address>
        {
            for $x in /root/r[LEVEL="1"]
            return  <field id="{data($x/Field)}">{data($x/VALUE)}</field>
        }
        <borrower>
        {
            for $x in /root/r[LEVEL="2"]
            return  <field id="{data($x/Field)}">{data($x/VALUE)}</field>
        }
        </borrower>
    </address>
</XmlFormat>');

输出

<XmlFormat version="1.0">
  <address>
    <field id="Address">testaddress</field>
    <field id="City">testcity</field>
    <borrower>
      <field id="FirstName">FN</field>
      <field id="LastName">LN</field>
    </borrower>
  </address>
</XmlFormat>

这是 C# 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication23
{

    class Program
    {

        static void Main(string[] args)
        {
            XElement address = new XElement("adress");

            XElement borrower = null;

            borrower = new XElement("field", new object[]
            {
                new XElement("field", new object[] {
                    new XAttribute("id", "FirstName"),
                    new XElement("value", "FN")
                })

            });
            address.Add(new XElement("borrower", borrower));

            borrower = new XElement("field", new object[]
            {
                new XElement("field", new object[] {
                    new XAttribute("id", "LastName"),
                    new XElement("value", "LN")
                })

            });
            address.Add(new XElement("borrower", borrower));

            borrower = new XElement("field", new object[]
            {
                new XElement("field", new object[] {
                    new XAttribute("id", "Address"),
                    new XElement("value", "testaddress")
                })

            });
            address.Add(new XElement("borrower", borrower));

            borrower = new XElement("field", new object[]
            {
                new XElement("field", new object[] {
                    new XAttribute("id", "City"),
                    new XElement("value", "testcity")
                })

            });
            address.Add(new XElement("borrower", borrower));



        }
    }
 
}