You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成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实体(比如&#x2;),但XML解析器仍然会判定这类实体表示的控制字符无效,因此必须直接移除。

内容的提问来源于stack exchange,提问作者vega_gf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:15:43