使用C# System.Xml.Serialization反序列化带属性XML为字符串列表
解决XML与JSON双反序列化的Dependency模型错误问题
问题场景
给定嵌套XML结构:
<dependency ref="pkg:maven/org.keycloak/keycloak-services@10.0.2?type=jar"> <dependency ref="pkg:maven/com.sun.mail/jakarta.mail@1.6.4?type=jar"/> <dependency ref="pkg:maven/org.glassfish/jakarta.json@1.1.6?type=jar"/> <!-- 其他子dependency省略 --> </dependency>
需要将其反序列化为C#模型,同时适配JSON格式(JSON中用dependsOn数组存储依赖引用),原模型代码报错:Xml attribute cannot be used in conjunction with XmlArray。
原错误模型代码:
[XmlType(TypeName = "dependency")] public class Dependency { public Dependency() { this.DependsOn = new List<string>(); } [XmlAttribute("ref")] [JsonProperty("ref")] public string Ref { get; set; } = string.Empty; [XmlArray("dependency")] [XmlAttribute("ref")] [JsonProperty("dependsOn")] public List<string> DependsOn { get; set; } }
错误原因
[XmlArray("dependency")]用于定义包含子元素的数组容器节点,但实际XML中没有外层容器,子<dependency>直接作为父节点的子元素,注解使用不符合结构。[XmlAttribute("ref")]与[XmlArray]逻辑冲突:前者标记属性,后者标记数组节点,且集合属性无法直接映射到单个属性值,因此触发报错。
修正方案
通过引入辅助类分离XML与JSON的序列化逻辑,实现两种格式的适配:
using System.Collections.Generic; using System.Linq; using System.Xml.Serialization; using Newtonsoft.Json; [XmlType(TypeName = "dependency")] public class Dependency { public Dependency() { DependsOn = new List<string>(); } [XmlAttribute("ref")] [JsonProperty("ref")] public string Ref { get; set; } = string.Empty; // 仅处理XML序列化/反序列化:捕获所有子<dependency>元素的ref属性 [XmlElement("dependency")] public List<DependencyRef> XmlDependsOn { get => DependsOn.Select(refValue => new DependencyRef { Ref = refValue }).ToList(); set => DependsOn = value.Select(depRef => depRef.Ref).ToList(); } // 仅处理JSON序列化/反序列化,XML序列化时忽略该属性 [JsonProperty("dependsOn")] [XmlIgnore] public List<string> DependsOn { get; set; } } // 辅助类:映射XML中子<dependency>元素的ref属性 public class DependencyRef { [XmlAttribute("ref")] public string Ref { get; set; } = string.Empty; }
方案说明
- XML适配:
XmlDependsOn通过[XmlElement("dependency")]捕获所有子<dependency>元素,辅助类DependencyRef读取每个元素的ref属性,再转换为DependsOn集合。 - JSON适配:
DependsOn用[JsonProperty("dependsOn")]映射JSON数组,[XmlIgnore]避免XML序列化时处理该属性。 - 双向转换:
XmlDependsOn的get/set方法实现List<string>与List<DependencyRef>的双向转换,保证两种格式的序列化逻辑互不干扰。
内容的提问来源于stack exchange,提问作者Vikneshwaran Seetharaman
相关产品推荐
相关产品推荐

