C#中XML序列化与反序列化的元素名称大小写差异处理咨询
解决C# XML序列化与反序列化元素名称差异的方案
你可以试试下面这两种不用XSLT或自定义序列化器的办法:
1. 用XmlAttributeOverrides动态覆盖序列化规则
原类保留用于反序列化的大写标签特性,序列化时通过XmlAttributeOverrides动态指定全小写的元素名称,不用修改原类结构。
示例代码:
// 原类保持不变,用于反序列化 [XmlRoot(ElementName = "Invoice")] public class Invoice { [XmlElement(ElementName = "Id")] public int Id { get; set; } [XmlElement(ElementName = "User-id")] public int UserId { get; set; } // 其他属性 } // 序列化方法 public void SerializeInvoiceToLowerXml(Invoice invoice, string filePath) { var overrides = new XmlAttributeOverrides(); // 覆盖根元素为小写 var rootAttr = new XmlAttributes { XmlRoot = new XmlRootAttribute("invoice") }; overrides.Add(typeof(Invoice), rootAttr); // 覆盖Id属性的元素名 var idAttr = new XmlAttributes { XmlElements = { new XmlElementAttribute("id") } }; overrides.Add(typeof(Invoice), nameof(Invoice.Id), idAttr); // 覆盖UserId属性的元素名 var userIdAttr = new XmlAttributes { XmlElements = { new XmlElementAttribute("user-id") } }; overrides.Add(typeof(Invoice), nameof(Invoice.UserId), userIdAttr); // 用覆盖后的规则创建序列化器 var serializer = new XmlSerializer(typeof(Invoice), overrides); using (var writer = new StreamWriter(filePath)) { serializer.Serialize(writer, invoice); } } // 反序列化直接用原类的特性 public Invoice DeserializeInvoiceFromUpperXml(string filePath) { var serializer = new XmlSerializer(typeof(Invoice)); using (var reader = new StreamReader(filePath)) { return (Invoice)serializer.Deserialize(reader); } }
这个方法的好处是不用额外写类,适合属性较多的场景,只需要在序列化时动态配置需要修改的元素名。
2. 专门的DTO类映射
创建一个用于序列化的DTO类,所有元素标签都设为小写,反序列化用原类,序列化前把原类的属性值映射到DTO类再序列化。
示例代码:
// 原反序列化类 [XmlRoot(ElementName = "Invoice")] public class Invoice { [XmlElement(ElementName = "Id")] public int Id { get; set; } [XmlElement(ElementName = "User-id")] public int UserId { get; set; } // 其他属性 } // 序列化用的DTO类 [XmlRoot(ElementName = "invoice")] public class InvoiceDto { [XmlElement(ElementName = "id")] public int Id { get; set; } [XmlElement(ElementName = "user-id")] public int UserId { get; set; } // 对应原类的其他属性 } // 映射并序列化 public void SerializeInvoiceDto(Invoice invoice, string filePath) { // 手动映射(或者用AutoMapper简化) var dto = new InvoiceDto { Id = invoice.Id, UserId = invoice.UserId // 其他属性映射 }; var serializer = new XmlSerializer(typeof(InvoiceDto)); using (var writer = new StreamWriter(filePath)) { serializer.Serialize(writer, dto); } } // 反序列化还是用原类 public Invoice DeserializeInvoice(string filePath) { var serializer = new XmlSerializer(typeof(Invoice)); using (var reader = new StreamReader(filePath)) { return (Invoice)serializer.Deserialize(reader); } }
这个办法更直观,代码可读性高,适合属性较少或者需要明确区分序列化/反序列化规则的场景。
内容的提问来源于stack exchange,提问作者Hub
相关产品推荐
相关产品推荐

