You need to enable JavaScript to run this app. 如何阻止XmlDocument加载XML时自动解码HTML十进制实体,保留原始编码格式
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止XmlDocument加载XML时自动解码HTML十进制实体,保留原始编码格式

关于XmlDocument自动解码十进制实体的问题解决方案

问题本质

&#xxxx;形式的十进制实体在调用LoadXml时被自动解码为实际字符,是符合XML 1.0规范的默认设计行为,没有官方提供的配置项可以直接关闭这个解析流程。
原因是XmlDocument基于标准DOM模型实现,DOM规范明确要求节点存储的是实体解析后的实际Unicode字符值,原始的实体语法文本在文档加载完成后就不会被保留,因此无论加载还是序列化阶段,都不存在“跳过实体解码、保留原始实体文本”的原生开关。

可行的落地实现方案

1. 自定义序列化流程,按规则将输出字符转回十进制实体格式

不需要修改加载阶段的逻辑,只需要在将修改后的DOM序列化为输出字符串时,拦截输出流程,将对应需要保留为实体格式的字符(比如解码回来的欧元符号)替换为对应的&#xxxx;十进制实体,完全对齐原始输入的文本格式。
核心实现是重写XmlWriter的字符串输出逻辑,代码示例:

public class DecimalEntityPreservingXmlWriter : XmlTextWriter
{
    public DecimalEntityPreservingXmlWriter(TextWriter writer) : base(writer)
    {
        // 保持和原XML一致的缩进格式,避免序列化后格式出现非预期偏差
        Formatting = Formatting.Indented;
    }

    public override void WriteString(string text)
    {
        var outputBuilder = new StringBuilder();
        foreach (char c in text)
        {
            // 可根据需求调整判断规则,对非ASCII字符统一替换为十进制实体格式输出
            if (c > 127)
            {
                outputBuilder.Append($"&#{(int)c};");
            }
            else
            {
                outputBuilder.Append(c);
            }
        }
        base.WriteString(outputBuilder.ToString());
    }
}

替换原有序列化逻辑的调用方式:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
// 原有节点定位、修改的逻辑完全保持不变
XmlNode node = xmlDoc.SelectSingleNode(".//var[@name='DecimalSeparator']");
node.Attributes["value"].Value = ".";

// 替换原来直接读取xmlDoc.OuterXml的逻辑
using var stringWriter = new StringWriter();
using var customWriter = new DecimalEntityPreservingXmlWriter(stringWriter);
xmlDoc.WriteTo(customWriter);
string modified = stringWriter.ToString();

这种方案的通用性远优于手动替换单个字符的临时方案:不管原始XML里的实体对应什么特殊字符,只要是从十进制实体解码回来的非ASCII字符,都会被自动按照&#编码;的格式重新输出,不存在需要手动维护映射表的覆盖盲区。

2. 替换DOM类组件,使用流处理模式全程保留原始文本

如果希望从根源上避免实体解码带来的内容偏差,可以放弃XmlDocument这类全量DOM解析组件,改用XmlReader的逐行流处理模式,核心逻辑是:

  • 加载XML时直接保留原始文本流,不做实体解析
  • 通过流定位到需要修改的节点位置,直接在原始文本上做定点替换
  • 输出时直接输出修改后的原始文本流,全程不经过DOM层的解码流程
    这种方式完全不会改变原始XML除目标修改节点外的任何内容,连原有的排版格式、实体写法都和输入完全一致,适合代理服务这类对输出一致性要求极高的场景。

常见误区

不要尝试通过修改XmlResolver配置、自定义实体字典的方式阻止字符实体解码:这类配置只能控制外部引用实体的加载行为,无法修改内置字符实体的默认解析逻辑,调整成本高且无法达到预期效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 06:27:00