XML序列化:将元素文本中整数序列转为List<int>的方法
优雅解决XML元素内容体转List的问题
这问题我之前也踩过坑!确实不用搞什么[XmlIgnore]再手动解析,.NET的XmlSerializer其实支持通过自定义类型转换器来自动处理这种空格分隔的数值列表,非常省心。
步骤1:实现自定义TypeConverter
先写一个继承自TypeConverter的转换器类,专门负责把空格分隔的字符串转成List<int>,反过来也能把List转成空格分隔的字符串:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; public class SpaceSeparatedIntListConverter : TypeConverter { // 判断是否能从字符串转换为List<int> public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } // 实现从字符串到List<int>的转换 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { return string.IsNullOrWhiteSpace(str) ? new List<int>() : str.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToList(); } return base.ConvertFrom(context, culture, value); } // 实现从List<int>到字符串的转换(序列化时用) public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string) && value is List<int> list) { return string.Join(" ", list); } return base.ConvertTo(context, culture, value, destinationType); } }
步骤2:在实体类中使用转换器
接下来定义你的XML实体类,用[XmlText]标记对应元素内容体的属性,同时加上自定义转换器的特性:
using System.Collections.Generic; using System.ComponentModel; using System.Xml.Serialization; [XmlRoot("SomeElement")] public class SomeElement { [XmlAttribute("SomeAttribute1")] public int SomeAttribute1 { get; set; } [XmlAttribute("SomeAttribute2")] public string SomeAttribute2 { get; set; } // 关键:用XmlText标记内容体,加上自定义转换器 [XmlText] [TypeConverter(typeof(SpaceSeparatedIntListConverter))] public List<int> Values { get; set; } = new List<int>(); }
步骤3:测试序列化/反序列化
这样不管是反解析XML还是生成XML,XmlSerializer都会自动帮你处理转换:
// 反序列化示例 var xml = @"<SomeElement SomeAttribute1=""10"" SomeAttribute2=""Bla""> 10 20 30 40 50 60 70 80 </SomeElement>"; var serializer = new XmlSerializer(typeof(SomeElement)); using var reader = new StringReader(xml); var element = (SomeElement)serializer.Deserialize(reader); // element.Values 就是包含10、20...80的List<int> // 序列化示例 var newElement = new SomeElement { SomeAttribute1 = 20, SomeAttribute2 = "Test", Values = new List<int> { 1,2,3,4 } }; using var writer = new StringWriter(); serializer.Serialize(writer, newElement); // 生成的XML内容体就是"1 2 3 4"
这种方式完全不用手动处理字符串分割和类型转换,代码更简洁也更符合XmlSerializer的设计逻辑,亲测好用!
内容的提问来源于stack exchange,提问作者oliver
相关产品推荐
相关产品推荐

