XML属性值映射至C#类的正确实现方式咨询
把XML映射到C# Article类的简洁方案
针对你给出的XML结构和Article类,这里有两种简洁且易维护的实现方式,你可以根据场景选择:
方案一:使用XmlSerializer(结构化映射)
如果这个XML结构会被重复使用,定义对应的中间类来序列化XML,再映射到Article是很清晰的做法,正好符合你想要的层级访问需求。
首先定义与XML结构对应的中间类:
using System.Xml.Serialization; using System.Collections.Generic; [XmlRoot("root")] public class Root { [XmlElement("table")] public Table Table { get; set; } } public class Table { [XmlElement("fields")] public Fields Fields { get; set; } } public class Fields { [XmlElement("field")] public List<Field> Field { get; set; } } public class Field { [XmlAttribute("name")] public string Name { get; set; } [XmlText] public string Value { get; set; } }
然后反序列化XML并映射到Article:
using System.IO; // 你的XML内容 var xmlContent = @"<root> <table> <fields> <field name=""createdby"">Thomas</field> <field name=""id"">123</field> <field name=""Title"">New Article</field> </fields> </table> </root>"; // 反序列化到中间类 var serializer = new XmlSerializer(typeof(Root)); using var stringReader = new StringReader(xmlContent); var xmlResult = (Root)serializer.Deserialize(stringReader); // 映射到Article类,加入空值判断避免异常 var article = new Article { CreatedBy = xmlResult.Table.Fields.Field.FirstOrDefault(f => f.Name.Equals("createdby", StringComparison.OrdinalIgnoreCase))?.Value ?? string.Empty, Id = xmlResult.Table.Fields.Field.FirstOrDefault(f => f.Name.Equals("id", StringComparison.OrdinalIgnoreCase))?.Value ?? string.Empty, Name = xmlResult.Table.Fields.Field.FirstOrDefault(f => f.Name.Equals("Title", StringComparison.OrdinalIgnoreCase))?.Value ?? string.Empty, Content = null // XML中没有该字段,设为默认值 };
这种方式的好处是结构清晰,后续XML结构调整时只需要修改中间类即可,适合重复使用的场景。
方案二:使用LINQ to XML(直接查询)
如果只是一次性的XML映射,不需要定义额外的中间类,直接用LINQ to XML查询赋值会更简洁:
using System.Xml.Linq; var xmlDoc = XDocument.Parse(xmlContent); var article = new Article { CreatedBy = xmlDoc.Descendants("field") .FirstOrDefault(f => (string)f.Attribute("name") == "createdby")?.Value ?? string.Empty, Id = xmlDoc.Descendants("field") .FirstOrDefault(f => (string)f.Attribute("name") == "id")?.Value ?? string.Empty, Name = xmlDoc.Descendants("field") .FirstOrDefault(f => (string)f.Attribute("name") == "Title")?.Value ?? string.Empty, Content = null };
这种方式省去了定义中间类的步骤,代码更紧凑,适合临时或简单的XML映射场景。
注意事项
两种方案都加入了FirstOrDefault和空值合并运算符,避免因为XML中缺少某个field而抛出异常,你可以根据实际需求调整空值处理逻辑。
内容的提问来源于stack exchange,提问作者Thomashdk




