自定义XML序列化:string[]属性CSV序列化与反序列化异常问题
解决XML序列化
string[]为CSV时的反序列化拆分错误问题 这个问题我之前也碰到过——核心矛盾就是你用空格作为数组元素的分隔符,但元素本身包含空格,导致反序列化时默认的空格拆分逻辑把单个元素拆成了多个。下面给你两种实用的解决方案,根据你的业务需求选择:
方案1:使用无冲突的自定义分隔符(推荐)
这种方法最稳妥,选一个不会出现在你的元素内容里的字符(比如|、;)作为分隔符,通过代理属性来处理序列化和反序列化的转换,避开元素内的空格干扰。
修改你的实体类
using System.Xml.Serialization; public class Choice { // 原数组属性,标记为XML序列化忽略 [XmlIgnore] public string[] Options { get; set; } // 用于XML序列化的代理属性,对应XML中的Options属性 [XmlAttribute("Options")] public string OptionsSerialized { get { // 序列化:把数组转成用|分隔的字符串 if (Options == null) return null; return string.Join("|", Options); } set { // 反序列化:把字符串按|拆分成数组 if (string.IsNullOrEmpty(value)) { Options = Array.Empty<string>(); return; } Options = value.Split('|'); } } }
测试效果
序列化代码执行后,生成的XML会是这样:
<Choice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Options="op 1|op 2" />
反序列化时,Options会被正确还原为包含"op 1"和"op 2"的数组,不会出现拆分错误。
方案2:必须保留空格作为分隔符时的转义处理
如果业务要求必须用空格作为分隔符,那我们需要对元素内的空格进行转义,反序列化时再还原回来:
修改代理属性逻辑
using System.Xml.Serialization; using System.Linq; public class Choice { [XmlIgnore] public string[] Options { get; set; } [XmlAttribute("Options")] public string OptionsSerialized { get { if (Options == null) return null; // 把元素内的空格替换为\s,再用空格分隔元素 var escapedItems = Options.Select(item => item.Replace(" ", "\\s")).ToArray(); return string.Join(" ", escapedItems); } set { if (string.IsNullOrEmpty(value)) { Options = Array.Empty<string>(); return; } // 先按空格拆分,再把每个元素里的\s还原为空格 var splitItems = value.Split(' '); Options = splitItems.Select(item => item.Replace("\\s", " ")).ToArray(); } } }
测试效果
序列化后生成的XML:
<Choice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Options="op\s1 op\s2" />
反序列化时,\s会被还原成空格,得到正确的两个元素。
为什么不用默认的XML序列化?
默认的XmlSerializer对数组的序列化逻辑是生成多个子元素,而不是属性值。你手动改成空格分隔的属性值后,反序列化时没有对应的自定义拆分逻辑,就会按空格直接拆分,自然会把带空格的元素拆碎——上面的代理属性方案就是给序列化/反序列化加了一层自定义逻辑,完美解决这个问题。
内容的提问来源于stack exchange,提问作者ulu
相关产品推荐
相关产品推荐

