【问题标题】:Deserialize an XML document containing character entity references反序列化包含字符实体引用的 XML 文档
【发布时间】:2019-10-20 14:31:12
【问题描述】:

我有一个非常古老的 XML 文档,它以此开头:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE mydoc [
    <!ENTITY reg   "&#174;">
    <!ENTITY micro "&#181;">
    <!ENTITY times "&#215;">
    <!ENTITY Agrave  "&#192;" ><!-- capital A, grave accent -->
    <!ENTITY Aacute  "&#193;" ><!-- capital A, acute accent -->
    <!ENTITY Acirc   "&#194;" ><!-- capital A, circumflex accent -->
    <!ENTITY Atilde  "&#195;" ><!-- capital A, tilde -->
    <!ENTITY Auml    "&#196;" ><!-- capital A, dieresis or umlaut mark -->
    <!ENTITY Aring   "&#197;" ><!-- capital A, ring -->
    <!ENTITY AElig   "&#198;" ><!-- capital AE diphthong (ligature) -->
    <!ENTITY Ccedil  "&#199;" ><!-- capital C, cedilla -->

...


    <!ENTITY uuml    "&#252;" ><!-- small u, dieresis or umlaut mark -->
    <!ENTITY yacute  "&#253;" ><!-- small y, acute accent -->
    <!ENTITY thorn   "&#254;" ><!-- small thorn, Icelandic -->
    <!ENTITY yuml    "&#255;" ><!-- small y, dieresis or umlaut mark -->
]>
<mydoc>
...

然后,在整个文档中,有如下几行:

<someelement>Text with &auml; or something</someelement>

我想用 C# 反序列化它。我使用xsd.exe 生成了一个.xsd,并用它来自动生成C# 类。我的反序列化代码很简单。

var serializer = new XmlSerializer(typeof(mydoc));
mydoc myDoc;

using (var fileStream = new FileStream(Path, FileMode.Open))
{
    myDoc = serializer.Deserialize(fileStream) as mydoc;

    if (myDoc == null)
    {
        throw new InvalidOperationException("Deserialization failed.");
    }
}

反序列化成功,但是当您检查反序列化的someelement 时,其Value 将是:

" or something"

我检查了包含特殊实体的其他行,它们都像这样在最后一个特殊实体处被切断。如何强制XmlSerializer 将该行另存为

"Text with ä or something"

额外的问题:这个文件有几个 gigs 大小,所以我想避免制作不必要的副本,我不能只是将整个文件加载到内存并在将其传递给序列化程序之前对其进行处理。

【问题讨论】:

  • 编辑了标题,因为这些实体与 HTTP 无关(它们恰好匹配 HTML 中使用的实体,但这与问题无关)。
  • 这在我看来就像您正在使用的工具中的一个错误。如果您无法说服供应商修复它,那么解决方法是通过使用其他工具执行解析/序列化操作来预处理文件。我对 .NET 上可用的工具不够熟悉,无法提供更具体的建议。
  • 根根元素必须更改为 mydoc 才能与 DOCTYPE 定义一致。
  • @jdweng 你说得对,我在这里重新输入时出错了。
  • 我需要查看实际 xml 的示例以提供帮助。该文件很大,因此您必须使用 XmlReader 来解析文件。其他方法会给出内存不足的异常。

标签: c# .net xml encoding .net-core


【解决方案1】:

我认为这是因为默认情况下禁用了 DTD 处理。

试试下面的代码:

var settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;

using (var xmlReader = XmlReader.Create(Path, settings))
{
    myDoc = serializer.Deserialize(xmlReader) as mydoc;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2014-08-31
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多