You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SQL查询数据在C#中通过循环生成订单XML(静态与循环结构)

用C# XDocument生成带动态订单行的XML文档

嘿,刚好我之前也做过类似的需求,用XDocument处理这种“静态部分+循环动态部分”的XML生成特别顺手,给你一步步拆解怎么实现:

核心思路

先把只需要出现一次的元素/属性(比如订单头、客户信息这些)先构建好,然后找到要容纳订单行的父节点,最后遍历你的订单行数据,逐个生成<OrderLine>元素并添加进去就行。

完整代码示例

假设你已经从SQL查询拿到了订单主数据和订单行的集合(这里用实体类模拟实际项目中的数据结构):

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

class OrderGenerator
{
    static void Main()
    {
        // 模拟从SQL获取的订单主数据(只生成一次的部分)
        var orderHeader = new OrderHeader
        { 
            OrderId = "ORD-2024-0012", 
            CustomerName = "Alice Smith", 
            OrderDate = DateTime.Now 
        };

        // 模拟从SQL获取的订单行数据(有N条就生成N个OrderLine)
        var orderLines = new List<OrderLine>
        {
            new OrderLine { ProductId = "PROD-100", Quantity = 2, UnitPrice = 29.99m },
            new OrderLine { ProductId = "PROD-200", Quantity = 1, UnitPrice = 59.99m },
            new OrderLine { ProductId = "PROD-300", Quantity = 3, UnitPrice = 9.99m }
        };

        // 1. 构建XML基础静态结构
        var orderDoc = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XElement("Order",
                new XAttribute("OrderId", orderHeader.OrderId),
                new XElement("CustomerDetails",
                    new XElement("Name", orderHeader.CustomerName),
                    new XElement("OrderDate", orderHeader.OrderDate.ToString("yyyy-MM-dd"))
                ),
                // 预留订单行的父容器节点
                new XElement("OrderItems")
            )
        );

        // 2. 找到订单行容器,循环添加动态订单行
        var orderItemsContainer = orderDoc.Descendants("OrderItems").FirstOrDefault();
        if (orderItemsContainer != null && orderLines.Any())
        {
            foreach (var line in orderLines)
            {
                orderItemsContainer.Add(
                    new XElement("OrderItem",
                        new XElement("ProductId", line.ProductId),
                        new XElement("Quantity", line.Quantity),
                        new XElement("UnitPrice", line.UnitPrice.ToString("0.00")),
                        new XElement("LineTotal", (line.Quantity * line.UnitPrice).ToString("0.00"))
                    )
                );
            }
        }
        // 如果没有订单行,可以选择移除空的OrderItems节点
        else if (orderItemsContainer != null)
        {
            orderItemsContainer.Remove();
        }

        // 3. 输出XML或保存到文件
        Console.WriteLine(orderDoc.ToString());
        // orderDoc.Save(@"D:\Orders\ORD-2024-0012.xml");
    }
}

// 实际项目中用实体类映射SQL返回的数据
public class OrderHeader
{
    public string OrderId { get; set; }
    public string CustomerName { get; set; }
    public DateTime OrderDate { get; set; }
}

public class OrderLine
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
}

关键细节提醒

  • 精准节点定位:用Descendants("OrderItems").FirstOrDefault()可以灵活定位到目标父节点,不用硬编码XML层级结构,后续修改XML结构时更省心。
  • 数据格式化:日期、金额这类数据要统一格式(比如日期用标准的yyyy-MM-dd,金额保留两位小数),避免下游系统解析XML时出现异常。
  • 空数据处理:如果订单行是空集合,可以选择移除<OrderItems>节点,避免生成空的冗余节点,让XML更干净。
  • 动态属性/元素:如果某些元素/属性需要按需生成(比如只有折扣的订单行才显示<Discount>元素),可以在创建XElement时加条件判断:line.Discount > 0 ? new XElement("Discount", line.Discount) : null,XDocument会自动忽略null的元素/属性。

这样生成的XML会根据订单行的数量自动生成对应个数的<OrderItem>,静态部分只会出现一次,完全符合你的需求~

内容的提问来源于stack exchange,提问作者Iain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:00:23