XmlDocument和XDocument处理方式的区别�

本文关键字:区别 #x0 方式 XDocument 处理 XmlDocument | 更新日期: 2023-09-27 18:18:48

我一直在尝试加载包含一些null('�')字符的xml文件。我试过了-

  XmlDocument document = new XmlDocument();
  document.LoadXml(xmlString);

XDocument.Load(stringReader);

XmlDocument.LoadXml()方法成功加载xml文档,而XDocument.Load()方法为相同的xml字符串提供XmlException

复制示例代码:

string xmlFile = @"C:'dummyData.xml";
        string xmlString = File.ReadAllText(xmlFile);
        XmlDocument document = new XmlDocument();
        document.LoadXml(xmlString); //Work
        XDocument.Parse(xmlString); // Didn't work.
        using (StringReader reader = new StringReader(xmlString))
        {
            XDocument.Load(reader);
        }
Xml文件

从这里复制xml文件的内容

XmlDocument和XDocument处理方式的区别�

为什么&有问题吗

根据W3C的定义,实体是

CharRef ::=   '&#' [0-9]+ ';'
            | '&#x' [0-9a-fA-F]+ ';'

所以乍一看,像�这样的实体看起来不错。

但是你需要阅读定义:

[定义:字符引用是指ISO/IEC 10646字符集中的特定字符,例如不能从可用输入设备直接访问的字符。]

所以字符引用需要指向ISO/IEC 10646字符,链接为:

使用字符引用引用的字符必须匹配Char的生成。

幸运的是,Char在同一个文档中,定义为:

Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

因此,正如Martin Honnen之前提到的,在XML文档中既不允许c# '0字符,也不允许转义版本��

XML解析器现实

一些解析器可能会忽略上述规则的部分内容,而不完全遵循标准。

问题的真正根源

您发布的XML似乎包含图像/绘图:

<?xml version="1.0" encoding="utf-8"?>
<TestData>
        <Images>
            <Drawings>
&lt;?xml version="1.0"?&gt;
&lt;ArrayOfMarkerState &gt;
&lt;/ArrayOfMarkerState&gt;
&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;&#x0;</Drawings>
        </Images>
            <Date>2015-10-20T17:19:05.2656609+05:30</Date>
</TestData>

像素图形的本质是它们包含二进制数据。

不熟悉XML并面临在XML中嵌入二进制数据问题的开发人员会很快认为任何字节都可以被编码为&#x00;&#xFF;

不幸的是,这是完全错误的。为什么?嗯,因为上面的W3C定义。

除此之外,这甚至是一个关于大小的坏主意。即使它可以工作,像这样编码的一个字节在XML中也需要6个字节。

解决原问题

二进制数据不能作为XML实体进入XML文档,所以让我们找到一些工作,并且需要的大小增加小于+500%。

答案是Base64。Base64的大小大约增加了33%。

编码47个&#x0;字节将产生

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

与原来的235字节相比,只有64字节。

在XML(至少是Microsoft支持的XML 1.0)中不允许字符引用&#x0;。然而,对于遗留支持,我认为XmlTextReaderXmlReaderXmlReaderSettings创建不检查字符可以加载这样的标记。XmlDocument使用这样的XmlReader,而XDocument没有。