如何将XML序列化/反序列化为C#对象?含多层XML示例
如何将XML序列化/反序列化为C#对象?
我来帮你一步步拆解这个问题,先讲通用的序列化/反序列化思路,再针对你提供的多层结构XML做具体实现。
一、通用的XML与C#对象互转方法
不管XML结构复杂与否,核心都是先定义匹配的C#类,再用.NET自带的XmlSerializer类完成转换。
1. 序列化(C#对象转XML)
- 第一步:定义匹配类:用
[XmlRoot]、[XmlElement]、[XmlAttribute]这些特性,把C#类的成员和XML的元素、属性一一对应起来。 - 第二步:执行序列化:用
XmlSerializer把对象写入文件或字符串。
示例代码:
using System.Xml.Serialization; using System.IO; // 示例类:匹配简单XML结构 [XmlRoot("Person")] public class Person { [XmlAttribute("ID")] // 对应XML中的属性<Person ID="1"> public int Id { get; set; } [XmlElement("FullName")] // 对应XML中的子元素<FullName>张三</FullName> public string Name { get; set; } } // 序列化方法 public static void SerializeToXml<T>(T obj, string savePath) { var serializer = new XmlSerializer(typeof(T)); using (var writer = new StreamWriter(savePath)) { serializer.Serialize(writer, obj); } }
2. 反序列化(XML转C#对象)
- 同样需要先定义好匹配的C#类,然后用
XmlSerializer的Deserialize方法读取XML内容并转换为对象。
示例代码:
public static T DeserializeFromXml<T>(string filePath) { var serializer = new XmlSerializer(typeof(T)); using (var reader = new StreamReader(filePath)) { return (T)serializer.Deserialize(reader); } }
二、针对你提供的XML字符串的具体实现
先把你给出的XML整理清晰:
return (<Response> <Business Number="99696" Name="My business" Address="" /> )return ( <Purchase PurchaseID="7" CustomerID="0" > <Item Name="item 1" Qty="100" UnitCost="10.0000" /> )<Item Name="item2" Qty="200" UnitCost="20.0000" />
这个XML是多层结构,还有多个<Item>列表,我们需要精准定义对应的C#类。
第一步:定义匹配的C#类
注意区分XML的属性(比如Number="99696")和子元素(比如<Purchase>):
using System.Xml.Serialization; using System.Collections.Generic; // 根元素<Response>对应的类 [XmlRoot("Response")] public class Response { // 对应<Business>子元素 [XmlElement("Business")] public Business BusinessInfo { get; set; } // 对应<Purchase>子元素 [XmlElement("Purchase")] public Purchase PurchaseDetails { get; set; } } // <Business>元素对应的类(里面的都是属性) public class Business { [XmlAttribute("Number")] public string Number { get; set; } [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Address")] public string Address { get; set; } } // <Purchase>元素对应的类 public class Purchase { [XmlAttribute("PurchaseID")] public int PurchaseID { get; set; } [XmlAttribute("CustomerID")] public int CustomerID { get; set; } // 多个<Item>子元素,用List接收,标记[XmlElement]而不是[XmlArray](因为没有外层<Items>包裹) [XmlElement("Item")] public List<Item> Items { get; set; } = new List<Item>(); } // <Item>元素对应的类 public class Item { [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Qty")] public int Quantity { get; set; } // 这里属性名可以和XML属性名不同,特性指定对应关系即可 [XmlAttribute("UnitCost")] public decimal UnitCost { get; set; } }
第二步:具体的序列化/反序列化代码
1. 反序列化XML字符串到C#对象
如果你的XML是字符串形式(不是文件),可以用StringReader来读取:
using System.Xml.Serialization; using System.IO; using System.Xml; public static Response DeserializeXmlString(string xmlContent) { var serializer = new XmlSerializer(typeof(Response)); using (var stringReader = new StringReader(xmlContent)) using (var xmlReader = XmlReader.Create(stringReader)) { return (Response)serializer.Deserialize(xmlReader); } } // 使用示例 string yourXml = @"<Response> <Business Number=""99696"" Name=""My business"" Address="""" /> <Purchase PurchaseID=""7"" CustomerID=""0"" > <Item Name=""item 1"" Qty=""100"" UnitCost=""10.0000"" /> <Item Name=""item2"" Qty=""200"" UnitCost=""20.0000"" /> </Purchase> </Response>"; Response result = DeserializeXmlString(yourXml); // 现在可以直接访问属性,比如: // Console.WriteLine(result.BusinessInfo.Name); // 输出 "My business" // Console.WriteLine(result.PurchaseDetails.Items[0].Quantity); // 输出 100
2. 序列化C#对象到XML字符串
如果你需要把构造好的Response对象转回XML字符串,可以用这个方法:
public static string SerializeResponseToXml(Response responseObj) { var serializer = new XmlSerializer(typeof(Response)); // 去除默认的XML声明(可选,根据你的需求调整) var namespaces = new XmlSerializerNamespaces(); namespaces.Add("", ""); using (var stringWriter = new StringWriter()) { serializer.Serialize(stringWriter, responseObj, namespaces); return stringWriter.ToString(); } } // 使用示例 var newResponse = new Response { BusinessInfo = new Business { Number = "54321", Name = "New Shop", Address = "456 Oak Ave" }, PurchaseDetails = new Purchase { PurchaseID = 15, CustomerID = 2, Items = new List<Item> { new Item { Name = "Laptop", Quantity = 10, UnitCost = 999.99m }, new Item { Name = "Mouse", Quantity = 50, UnitCost = 25.50m } } } }; string xmlOutput = SerializeResponseToXml(newResponse);
几个关键注意点
- 类型匹配要准确:比如XML里的
Qty是整数,C#里就用int;UnitCost是小数,用decimal避免精度丢失。 - 列表处理:如果XML是直接多个同名称元素(比如这里的
<Item>),用[XmlElement]标记列表;如果是<Items><Item>...</Item></Items>这种包裹式列表,才用[XmlArray]+[XmlArrayItem]。 - 命名空间:如果XML包含命名空间,需要在
XmlRoot或XmlElement特性中指定Namespace属性。
内容的提问来源于stack exchange,提问作者ruben
相关产品推荐
相关产品推荐

