C# XML序列化:保留列表包装标签,移除列表项包装标签
保留XML列表包装标签并移除列表项的包裹标签
要实现保留PartnerContacts包装标签,同时移除每个PartnerContact项的包裹标签,直接将联系人的属性元素放在PartnerContacts下,推荐以下两种实现方式:
方法一:实现IXmlSerializable接口自定义序列化
这种方式可以完全控制XML生成结构,精准匹配你的需求:
修改Partner类并实现IXmlSerializable接口:
using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; public class Partner : IXmlSerializable { public List<PartnerContact> PartnerContacts { get; set; } = new List<PartnerContact>(); public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { // 按需实现反序列化逻辑,示例仅处理核心结构 reader.ReadStartElement("Partner"); if (reader.Name == "PartnerContacts") { reader.ReadStartElement("PartnerContacts"); while (reader.Name == "ContactType") { var contact = new PartnerContact { ContactType = reader.ReadElementContentAsString(), Name = reader.ReadElementContentAsString("Name", ""), PhoneNumber = reader.ReadElementContentAsString("PhoneNumber", ""), EmailAddress = reader.ReadElementContentAsString("EmailAddress", "") }; PartnerContacts.Add(contact); } reader.ReadEndElement(); } reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { writer.WriteStartElement("PartnerContacts"); foreach (var contact in PartnerContacts) { writer.WriteElementString("ContactType", contact.ContactType); writer.WriteElementString("Name", contact.Name); writer.WriteElementString("PhoneNumber", contact.PhoneNumber); writer.WriteElementString("EmailAddress", contact.EmailAddress); } writer.WriteEndElement(); } } public class PartnerContact { public string ContactType { get; set; } public string Name { get; set; } public string PhoneNumber { get; set; } public string EmailAddress { get; set; } }
方法二:使用XmlAttributeOverrides动态配置序列化规则
如果不想修改原有类结构,可以通过动态属性覆盖实现:
using System.Xml.Serialization; var overrides = new XmlAttributeOverrides(); // 移除PartnerContact的默认包裹标签 var contactAttrs = new XmlAttributes { XmlRoot = null }; overrides.Add(typeof(PartnerContact), contactAttrs); // 配置PartnerContacts为包装标签,并指定内部属性的序列化方式 var listAttrs = new XmlAttributes(); listAttrs.XmlArray = new XmlArrayAttribute("PartnerContacts"); // 为每个联系人属性添加XmlElement标记,让属性直接作为包装标签的子元素 foreach (var prop in typeof(PartnerContact).GetProperties()) { listAttrs.XmlArrayItems.Add(new XmlElementAttribute(prop.Name)); } overrides.Add(typeof(Partner), "PartnerContacts", listAttrs); // 使用自定义配置的序列化器 var serializer = new XmlSerializer(typeof(Partner), overrides);
测试序列化代码
以方法一为例,测试代码如下:
var partner = new Partner { PartnerContacts = new List<PartnerContact> { new PartnerContact { ContactType = "AR", Name = "John Doe", PhoneNumber = "0123456789", EmailAddress = "test@test.com" }, new PartnerContact { ContactType = "OR", Name = "John Does wife", PhoneNumber = "987654321", EmailAddress = "test@test.com" } } }; using var writer = new StringWriter(); var serializer = new XmlSerializer(typeof(Partner)); serializer.Serialize(writer, partner); Console.WriteLine(writer.ToString());
运行后会输出你期望的XML结构:
<Partner> <PartnerContacts> <ContactType>AR</ContactType> <Name>John Doe</Name> <PhoneNumber>0123456789</PhoneNumber> <EmailAddress>test@test.com</EmailAddress> <ContactType>OR</ContactType> <Name>John Does wife</Name> <PhoneNumber>987654321</PhoneNumber> <EmailAddress>test@test.com</EmailAddress> </PartnerContacts> </Partner>
内容的提问来源于stack exchange,提问作者D. Brugmans
相关产品推荐
相关产品推荐

