生成XML文档时遇0x02无效字符错误,求解决方法
解决XML序列化时“十六进制值0x02是无效字符”的问题
问题原因
XML 1.0规范明确禁止包含0x00-0x08、0x0B-0x0C、0x0E-0x1F这类控制字符,0x02属于这个禁用范围。这类字符无法通过编码处理规避,必须从源数据中移除才能完成序列化。
解决方案
在序列化前,遍历InvoiceType对象的所有字符串属性,过滤掉无效的XML控制字符。
1. 编写字符清理方法
这个方法会保留XML允许的字符,移除所有禁用的控制字符:
public static string CleanInvalidXmlCharacters(string input) { if (string.IsNullOrWhiteSpace(input)) return input; // 仅保留XML 1.0允许的字符 var validChars = input.Where(c => c == '\t' || c == '\n' || c == '\r' || (c >= '\u0020' && c <= '\uD7FF') || (c >= '\uE000' && c <= '\uFFFD') || (c >= '\u10000' && c <= '\u10FFFF')); return new string(validChars.ToArray()); }
2. 清理对象中的字符串字段
在序列化前,对doc对象的所有字符串属性执行清理。如果是嵌套对象,需要递归处理:
// 示例:手动清理InvoiceType的字符串属性(根据实际字段调整) doc.InvoiceNumber = CleanInvalidXmlCharacters(doc.InvoiceNumber); doc.CustomerName = CleanInvalidXmlCharacters(doc.CustomerName); // 其他字符串字段依次处理... // 之后再执行序列化 using MemoryStream ms = new(); var XML = new XmlSerializer(typeof(InvoiceType)); var encoding = Encoding.UTF8; using (StreamWriter sw = new StreamWriter(ms, encoding)) { XML.Serialize(sw, doc, @namespace); } return ms.ToArray();
3. 批量处理(可选)
如果对象结构复杂,可以用反射批量遍历所有字符串属性并清理:
public static void CleanObjectXmlCharacters(object obj) { if (obj == null) return; var properties = obj.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance) .Where(p => p.PropertyType == typeof(string) && p.CanRead && p.CanWrite); foreach (var prop in properties) { string value = (string)prop.GetValue(obj); if (value != null) { prop.SetValue(obj, CleanInvalidXmlCharacters(value)); } } // 递归处理嵌套对象(根据需要调整) var nestedProperties = obj.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance) .Where(p => !p.PropertyType.IsValueType && p.PropertyType != typeof(string) && p.CanRead); foreach (var prop in nestedProperties) { object nestedObj = prop.GetValue(obj); CleanObjectXmlCharacters(nestedObj); } }
使用时只需在序列化前调用:
CleanObjectXmlCharacters(doc);
为什么之前的方法无效
编码处理只是将字符转换为字节流,无法改变字符本身在XML规范中的合法性。提前编码字符串会导致这些控制字符被转义成XML实体(比如),但XML解析器仍然会判定这类实体表示的控制字符无效,因此必须直接移除。
内容的提问来源于stack exchange,提问作者vega_gf
相关产品推荐
相关产品推荐

