.NET XmlDocument LoadXML 和实体

Posted

技术标签:

【中文标题】.NET XmlDocument LoadXML 和实体【英文标题】:.NET XmlDocument LoadXML and Entities 【发布时间】:2008-09-30 12:51:19 【问题描述】:

将 XML 加载到 XmlDocument 中时,即

XmlDocument 文档 = 新 XmlDocument(); document.LoadXml(xmlData);

有没有办法阻止进程替换实体?我有一个奇怪的问题,我在 xml 中有一个 TM 符号(存储为实体 #8482)被转换为 TM 字符。就我而言,这不应该发生,因为 XML 文档具有编码 ISO-8859-1(没有 TM 符号)

谢谢

【问题讨论】:

【参考方案1】:

这是对 XML 工具集的标准误解。整个业务带有“”,是一种旨在应对字符编码的句法特征。您的 XmlDocument 不是字符流——它已经摆脱了字符编码问题——而是包含 XML 类型数据的抽象模型。这方面的词包括 DOM 和 InfoSet,我不确定哪个是准确的。

"" gubbins 在此模型中将不存在,因为整个问题无关紧要,如果合适的话,当您将信息集转换回某种特定编码的字符流时,它将返回。

这种误解非常普遍,以至于将其作为类似怪癖集合的一部分写入学术文献。看看这个位置的“Xml Fever”:http://doi.acm.org/10.1145/1364782.1364795

【讨论】:

【参考方案2】:

你在写什么?一个文字作家?流?什么?

以下内容保留实体(好吧,它用十六进制等效项替换它) - 但如果您对 StringWriter 执行相同操作,它会检测到 unicode 并改用它:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(@"<xml>&#8482;</xml>");
    using (MemoryStream ms = new MemoryStream())
    
        XmlWriterSettings settings = new  XmlWriterSettings();
        settings.Encoding = Encoding.GetEncoding("ISO-8859-1");
        XmlWriter xw = XmlWriter.Create(ms, settings);
        doc.Save(xw);
        xw.Close();
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    

输出:

    <?xml version="1.0" encoding="iso-8859-1"?><xml>&#x2122;</xml>

【讨论】:

【参考方案3】:

我承认 XML 文档和编码有点令人困惑,但我希望当你再次保存它时它会被设置为适当的,如果你仍在使用 ISO-8859-1 - 但是如果你保存使用 UTF-8,就不需要了。在某些方面,从逻辑上讲,文档确实包含符号而不是实体引用——后者只是一个编码问题。 (我在这里大声思考-请不要将此作为权威信息。)

文件加载后你在做什么?

【讨论】:

最终我将字符输出到网页。问题是字符在显示上被破坏了,因为我将 responseEncoding 设置为 ISO-88559-1 您是如何将数据写入网页的?如果您使用编码为 ISO-8859-1 的 TextWriter 将其写出来,我希望它能够放入正确的字符实体。(您真的必须首先使用 ISO-8859-1,顺便说一句?) 我将它作为字符串存储在 DTO 中。这是通过查找特定节点然后执行 string fieldValue = ((XmlNode)fieldListEnum.Current).FirstChild.Value 从 XML 检索的。我最终使用一些数据绑定代码将它写到中继器 我不明白的是,如果数据以不可知的方式存储在 xml 编码中,为什么它不能正常工作 所以你在 FirstChild.Value 中得到了 unicode 字符——它是从字符实体中解码出来的。听起来您需要查看的不是 XML 文档,而是转发器。我建议您暂时忽略 XML 并尝试将字符(硬编码)写入转发器。【参考方案4】:

我相信如果您将实体内容包含在 CDATA 部分中,它应该不理会它,例如

<root>
<testnode>
<![CDATA[some text &#8482;]]>
</testnode>
</root>

【讨论】:

【参考方案5】:

实体引用不是特定于编码的。根据W3C XML 1.0 Recommendation:

如果字符引用以 "",数字和字母最多 终止;提供一个 的十六进制表示 ISO/IEC 中字符的代码点 10646.

【讨论】:

也许不是在阅读时——但在写作时是这样,因为该编码中可能不存在某些代码点,因此需要字符引用;所以真正归结为 OP 如何写入数据。【参考方案6】:

xxx;实体被认为是它们所代表的字符。所有 XML 在读取时都会转换为 unicode,并且任何此类实体都将被删除以支持它们所代表的 unicode 字符。这包括它们在 unicode 源中出现的任何情况,例如传递给 LoadXML 的字符串。

类似地,在写入任何不能由正在写入的流表示的字符时,将转换为 xxx;实体。试图保护它们毫无意义。

一个常见的错误是期望通过某种方式从 DOM 中获取字符串,该方式使用除 unicode 之外的编码。无论发生什么,这都不会发生

【讨论】:

【参考方案7】:

感谢大家的帮助。

我已经通过编写一个 htmlEncode 函数解决了我的问题,该函数实际上会在将所有字符吐出到网页之前替换所有字符(而不是依赖似乎只编码一小部分的有点损坏的 HtmlEncode() .NET 函数必要字符的子集)

【讨论】:

以上是关于.NET XmlDocument LoadXML 和实体的主要内容,如果未能解决你的问题,请参考以下文章

为啥包含 XML 标头时 C# XmlDocument.LoadXml(string) 会失败?

试图解析 xml,但 xmldocument.loadxml() 正在尝试下载?

原创XmlDocument.LoadXml和Load的区别

不使用 XmlDocument.Loadxml() 函数将 XML 反序列化为 JSON

将 XmlDocument 输出为 XML

将 xmlDocument 对象数据转换为 pdf