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

如何用StringBuilder和foreach循环构建不重复OrderId的XML

解决重复OrderId的XML生成问题

要实现相同OrderId只输出一次头部、循环输出对应明细的XML,核心思路是先按OrderId分组数据,再遍历每个分组生成订单节点——每个分组对应一个订单,先写一次头部,再遍历组内所有行生成明细。

步骤拆解与代码实现

1. 先准备数据结构(以DataReader为例)

如果你的sdrForEach是SqlDataReader,首先需要把数据读取到可分组的集合中(因为DataReader是只读向前的,无法重复遍历):

// 定义实体类存储每行数据
public class OrderDetail
{
    public int OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public string CustomerName { get; set; }
    public int ItemId { get; set; }
    public string ItemName { get; set; }
    public int Quantity { get; set; }
}

// 从DataReader读取数据到列表
List<OrderDetail> orderList = new List<OrderDetail>();
while (sdrForEach.Read())
{
    orderList.Add(new OrderDetail
    {
        OrderId = sdrForEach.GetInt32(sdrForEach.GetOrdinal("OrderId")),
        OrderDate = sdrForEach.GetDateTime(sdrForEach.GetOrdinal("OrderDate")),
        CustomerName = sdrForEach.GetString(sdrForEach.GetOrdinal("CustomerName")),
        ItemId = sdrForEach.GetInt32(sdrForEach.GetOrdinal("ItemId")),
        ItemName = sdrForEach.GetString(sdrForEach.GetOrdinal("ItemName")),
        Quantity = sdrForEach.GetInt32(sdrForEach.GetOrdinal("Quantity"))
    });
}

2. 按OrderId分组(可选:包含头部字段确保一致性)

如果担心同一OrderId的头部信息(比如OrderDate、CustomerName)可能不一致,可以把这些字段也加入分组键,避免生成错误的XML:

// 按OrderId+头部信息分组,确保同一组的头部完全一致
var groupedOrders = orderList.GroupBy(o => new 
{ 
    o.OrderId, 
    o.OrderDate, 
    o.CustomerName 
});

3. 遍历分组生成XML

现在用foreach遍历每个分组,先写订单头部,再遍历组内明细:

StringBuilder xmlBuilder = new StringBuilder();
xmlBuilder.AppendLine("<Orders>");

foreach (var orderGroup in groupedOrders)
{
    // 获取当前订单的头部信息(分组的Key)
    var header = orderGroup.Key;
    
    // 写入订单头部节点
    xmlBuilder.AppendLine("  <Order>");
    xmlBuilder.AppendLine($"    <OrderId>{header.OrderId}</OrderId>");
    xmlBuilder.AppendLine($"    <OrderDate>{header.OrderDate:yyyy-MM-dd}</OrderDate>");
    xmlBuilder.AppendLine($"    <CustomerName>{EscapeXml(header.CustomerName)}</CustomerName>");
    xmlBuilder.AppendLine("    <Items>");
    
    // 遍历当前订单的所有明细行
    foreach (var item in orderGroup)
    {
        xmlBuilder.AppendLine("      <Item>");
        xmlBuilder.AppendLine($"        <ItemId>{item.ItemId}</ItemId>");
        xmlBuilder.AppendLine($"        <ItemName>{EscapeXml(item.ItemName)}</ItemName>");
        xmlBuilder.AppendLine($"        <Quantity>{item.Quantity}</Quantity>");
        xmlBuilder.AppendLine("      </Item>");
    }
    
    // 闭合明细和订单节点
    xmlBuilder.AppendLine("    </Items>");
    xmlBuilder.AppendLine("  </Order>");
}

xmlBuilder.AppendLine("</Orders>");

// 辅助方法:转义XML特殊字符(避免&、<、>等导致XML无效)
private string EscapeXml(string input)
{
    if (string.IsNullOrEmpty(input)) return input;
    return input.Replace("&", "&amp;")
                .Replace("<", "&lt;")
                .Replace(">", "&gt;")
                .Replace("\"", "&quot;")
                .Replace("'", "&apos;");
}

关键注意点

  • XML特殊字符转义:一定要用EscapeXml这类方法处理用户输入的文本,否则如果内容包含&、<等字符,会生成无效的XML。
  • 分组的安全性:如果业务上同一OrderId的头部信息可能不一致,一定要把头部字段加入分组键,避免把不同头部的订单合并到一起。
  • 数据读取的必要性:如果用的是DataReader,必须先把数据读到集合中再分组,因为DataReader无法回溯遍历。

示例输出(对应你的需求)

假设你的原始数据是:

OrderIdOrderDateCustomerNameItemIdItemNameQuantity
1012024-05-01John Doe1Laptop1
1012024-05-01John Doe2Mouse2
1022024-05-02Jane Smith3Keyboard1

生成的XML会是:

<Orders>
  <Order>
    <OrderId>101</OrderId>
    <OrderDate>2024-05-01</OrderDate>
    <CustomerName>John Doe</CustomerName>
    <Items>
      <Item>
        <ItemId>1</ItemId>
        <ItemName>Laptop</ItemName>
        <Quantity>1</Quantity>
      </Item>
      <Item>
        <ItemId>2</ItemId>
        <ItemName>Mouse</ItemName>
        <Quantity>2</Quantity>
      </Item>
    </Items>
  </Order>
  <Order>
    <OrderId>102</OrderId>
    <OrderDate>2024-05-02</OrderDate>
    <CustomerName>Jane Smith</CustomerName>
    <Items>
      <Item>
        <ItemId>3</ItemId>
        <ItemName>Keyboard</ItemName>
        <Quantity>1</Quantity>
      </Item>
    </Items>
  </Order>
</Orders>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:51:20