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

在C#中动态将XML反序列化为List<T>类型的实现方案

嘿,我来帮你搞定把QBPOSXML的SalesOrderRet反序列化为C# List集合的事儿!这步骤其实挺清晰的,我给你拆解成几个关键部分:

第一步:定义匹配QBPOSXML结构的实体类

首先得把QBPOSXML的结构映射成C#的实体类——毕竟反序列化的核心就是让.NET能把XML节点对应到类的属性上。假设你的XML结构大概是这样的(如果和实际有出入,你只需要调整类的属性和特性就行):

return (<QBPOSXML>
  <SalesOrderRet>
    <TxnID>SO-001</TxnID>
    <SalesOrderItemRet>
      <ItemRef><FullName>Wireless Mouse</FullName></ItemRef>
      <Quantity>3</Quantity>
    </SalesOrderItemRet>
  </SalesOrderRet>
  <SalesOrderRet>
    <TxnID>SO-002</TxnID>
    <SalesOrderItemRet>
      <ItemRef><FullName>Mechanical Keyboard</FullName></ItemRef>
      <Quantity>1</Quantity>
    </SalesOrderItemRet>
  </SalesOrderRet>
</QBPOSXML>
)

对应的C#实体类要加上XML序列化特性,确保和XML节点完全匹配:

using System.Xml.Serialization;

// 根节点类,用来包裹所有SalesOrderRet条目
[XmlRoot("QBPOSXML")]
public class QbPosXmlRoot
{
    // 用XmlElement指定元素名,这样多个SalesOrderRet会被识别为同级集合
    [XmlElement("SalesOrderRet")]
    public List<SalesOrderRet> SalesOrders { get; set; } = new List<SalesOrderRet>();
}

// 订单主数据实体类
public class SalesOrderRet
{
    [XmlElement("TxnID")]
    public string TransactionId { get; set; }

    // 订单子项集合,同样用XmlElement指定子元素名
    [XmlElement("SalesOrderItemRet")]
    public List<SalesOrderItemRet> OrderItems { get; set; } = new List<SalesOrderItemRet>();

    // 这里可以根据你的XML结构添加其他字段,比如CustomerRef、TxnDate、TotalAmount等
}

// 订单项实体类
public class SalesOrderItemRet
{
    [XmlElement("ItemRef")]
    public ItemReference ItemReference { get; set; }

    [XmlElement("Quantity")]
    public decimal Quantity { get; set; }

    // 按需添加Price、Amount等其他字段
}

// 商品引用子类
public class ItemReference
{
    [XmlElement("FullName")]
    public string ProductName { get; set; }
}

这里要注意几个细节:

  • XML是区分大小写的,所以XmlElement特性里的名称必须和XML节点完全一致
  • 如果你的XML带有命名空间,要在XmlRoot和XmlElement里加上Namespace="你的XML命名空间"
  • 对于可能缺失的可选字段,用可空类型(比如decimal? Quantity)或者设置IsNullable=true避免反序列化报错
第二步:编写反序列化逻辑

接下来用.NET自带的XmlSerializer实现反序列化,不用额外安装第三方包。我写了两种常用场景的版本:

using System.IO;
using System.Xml.Serialization;

public class QbPosXmlParser
{
    // 从XML字符串反序列化为订单集合
    public List<SalesOrderRet> DeserializeFromXmlString(string xmlContent)
    {
        var serializer = new XmlSerializer(typeof(QbPosXmlRoot));
        
        using var stringReader = new StringReader(xmlContent);
        var root = (QbPosXmlRoot)serializer.Deserialize(stringReader);
        
        return root.SalesOrders;
    }

    // 从本地XML文件反序列化为订单集合
    public List<SalesOrderRet> DeserializeFromXmlFile(string filePath)
    {
        var serializer = new XmlSerializer(typeof(QbPosXmlRoot));
        
        using var streamReader = new StreamReader(filePath);
        var root = (QbPosXmlRoot)serializer.Deserialize(streamReader);
        
        return root.SalesOrders;
    }
}
第三步:调用示例

写完解析类,调用起来就很简单了,给你整个实际调用的例子:

// 模拟的QBPOSXML字符串
string sampleXml = @"<QBPOSXML>
                        <SalesOrderRet>
                            <TxnID>SO-001</TxnID>
                            <SalesOrderItemRet>
                                <ItemRef><FullName>Wireless Mouse</FullName></ItemRef>
                                <Quantity>3</Quantity>
                            </SalesOrderItemRet>
                        </SalesOrderRet>
                        <SalesOrderRet>
                            <TxnID>SO-002</TxnID>
                            <SalesOrderItemRet>
                                <ItemRef><FullName>Mechanical Keyboard</FullName></ItemRef>
                                <Quantity>1</Quantity>
                            </SalesOrderItemRet>
                        </SalesOrderRet>
                    </QBPOSXML>";

// 初始化解析器并反序列化
var parser = new QbPosXmlParser();
List<SalesOrderRet> orders = parser.DeserializeFromXmlString(sampleXml);

// 遍历处理订单数据
foreach (var order in orders)
{
    Console.WriteLine($"订单ID: {order.TransactionId}");
    foreach (var item in order.OrderItems)
    {
        Console.WriteLine($"  商品: {item.ItemReference.ProductName}, 数量: {item.Quantity}");
    }
}
容易踩的坑及解决办法
  • 元素名称不匹配:务必确保XmlElement特性里的名称和XML节点完全一致(包括大小写),不然会出现字段为空的情况
  • 命名空间问题:如果XML带有命名空间,一定要在所有相关类的XML特性里指定对应的命名空间,否则反序列化会失败
  • 空/缺失元素:对于可能不存在的字段,用可空类型或者设置IsNullable=true,避免抛出反序列化异常

内容的提问来源于stack exchange,提问作者B. Abdo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:16:48