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

如何阻止XDocument解析XML中的字符实体?

问题

读取并处理XML数据时,XML文档包含ISO字符实体(如↶),需要保留这些实体编码,但使用XDocument.Load()加载时,实体会被自动解析为对应符号。如何阻止这种解析行为?

示例XML

<?xml version="1.0" encoding="UTF-8"?>
<doc>
<table>
    <title>iso-amsa.ent</title>
    <tgroup cols="3">
        <colspec colname="col1" colwidth="0.50*"/>
        <colspec colname="col2" align="center" colwidth="0.40*"/>
        <colspec colname="col3" colwidth="2.20*"/>
        <thead>
            <row><entry><para>ISO Entity Name</para></entry><entry><para>Unicode Entity</para></entry><entry><para>Description</para></entry></row>
        </thead>
        <tbody>
            <row><entry><para>cularr</para></entry><entry><para>&#x21B6;</para></entry><entry><para>ANTICLOCKWISE TOP SEMICIRCLE ARROW</para></entry></row>
            <row><entry><para>curarr</para></entry><entry><para>&#x21B7;</para></entry><entry><para>CLOCKWISE TOP SEMICIRCLE ARROW</para></entry></row>
            <row><entry><para>dArr</para></entry><entry><para>&#x21D3;</para></entry><entry><para>DOWNWARDS DOUBLE ARROW</para></entry></row>
            <row><entry><para>darr2</para></entry><entry><para>&#x21CA;</para></entry><entry><para>DOWNWARDS PAIRED ARROWS</para></entry></row>
            <row><entry><para>dharl</para></entry><entry><para>&#x21C3;</para></entry><entry><para>DOWNWARDS HARPOON WITH BARB LEFTWARDS</para></entry></row>
        </tbody>
    </tgroup>
</table>
</doc>

当前加载代码

string fileName = @"C:\MyTestFile.xml";

XDocument _doc = XDocument.Load(fileName);

解决方案

XDocument默认会自动解析XML中的字符实体,要保留实体编码,需通过预转义或自定义读取逻辑实现,以下是几种可行方法:

方法1:预转义数字字符实体(推荐)

读取XML原始文本,用正则表达式精准匹配数字形式的字符实体并转义,避免破坏XML标准实体(如&lt;、&gt;):

using System.Text.RegularExpressions;
using System.IO;

string fileName = @"C:\MyTestFile.xml";
// 读取XML原始内容
string rawXml = File.ReadAllText(fileName);
// 仅转义数字字符实体,保留标准实体引用
string escapedXml = Regex.Replace(rawXml, @"&#(x?[0-9A-Fa-f]+);", @"&amp;#$1;");
// 解析转义后的XML
XDocument _doc = XDocument.Parse(escapedXml);

方法2:全局替换(适用于无标准实体的场景)

如果XML中仅包含数字字符实体、无标准实体引用,可直接全局替换:

using System.IO;

string fileName = @"C:\MyTestFile.xml";
string rawXml = File.ReadAllText(fileName);
string escapedXml = rawXml.Replace("&#", "&amp;#");
XDocument _doc = XDocument.Parse(escapedXml);

方法3:自定义XmlReader遍历构建XDocument(复杂场景)

若需要深度定制实体处理逻辑,可使用XmlReader遍历节点,手动捕获实体原始字符串并构建XDocument:

using System.Xml;
using System.Xml.Linq;

string fileName = @"C:\MyTestFile.xml";
XDocument doc = new XDocument();
XElement currentElement = null;

using (XmlReader reader = XmlReader.Create(fileName))
{
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                var element = new XElement(reader.Name);
                // 处理属性
                if (reader.HasAttributes)
                {
                    while (reader.MoveToNextAttribute())
                    {
                        element.Add(new XAttribute(reader.Name, reader.Value));
                    }
                    reader.MoveToElement();
                }
                currentElement = currentElement == null ? doc.Add(element).FirstNode as XElement : currentElement.Add(element).LastNode as XElement;
                // 自闭合标签回退父节点
                if (reader.IsEmptyElement) currentElement = currentElement.Parent;
                break;
            case XmlNodeType.Text:
                currentElement.Add(reader.Value);
                break;
            case XmlNodeType.EntityReference:
                // 保留实体原始字符串
                currentElement.Add($"&{reader.Name};");
                break;
            case XmlNodeType.EndElement:
                currentElement = currentElement.Parent;
                break;
        }
    }
}

此方法实现复杂度较高,适合需要精细控制的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:25:30