【问题标题】:Referencing external named character entities when using XmlReader?使用 XmlReader 时引用外部命名字符实体?
【发布时间】:2011-04-08 14:35:24
【问题描述】:

我想在 XmlReader 实例上使用 C#/.NET 引用具有字符实体的 URL,例如 this w3c entity set 定义   和其他字符。

如果我要在纯 XML 中完成它,它会是这样的,或者是一个变体:
<!ENTITY foo SYSTEM "http://example.org/myent.ent">

我实际上是阅读 XHTML 源代码的片段(包含命名实体),因此需要定义/识别名为 Entity Sets defined by w3c 的 XML 1.0/HTML 4
(我在问如何以编程方式在设置 XmlReader 及其设置以读取片段时即时引用它们;但是我愿意选择)。

无论哪种方式,如果我不包含这些命名实体,读者会咳嗽并产生 .NET 错误,例如   和其他非数字实体的以下 XmlException:

测试“Xml_Tester.Test_Reading”失败: System.Xml.XmlException:参考 未声明的实体“nbsp”。 6号线, 位置 393。

注意:我使用 XmlReaderSettings.Schemas 集合属性成功引用了 XHTML Schema,并假设必须有一种同样简单的方法来调用外部实体引用,而无需修改 XML 源,但它避开了我。


等:

我在搜索答案时遇到了以下重要信息位 - 它们在这里可能很有用...

对实体的支持
要使用实体,作者必须使用 DTD 机制。请参阅第 1.5 节以一起使用 DTD 和 XML Schema。 -- http://www.w3.org/TR/xhtml1-schema/#diffs

1.5。一起使用 DTD 和 XML Schema
DTD 验证和 XML 模式验证不是相互排斥的。有时作者可能希望在利用 XML Schema 验证的同时使用一些 DTD 特性(例如实体)。 -- http://www.w3.org/TR/xhtml1-schema/#together

将 XML 文档与 XInclude 结合
外部实体必须在 DTD 或内部子集中声明。这打开了一个充满暗示的潘多拉魔盒,例如文档元素必须在 Doctype 声明中命名,验证读者可能需要在 DTD 等中定义文档的完整内容模型。
-- http://msdn.microsoft.com/en-us/library/aa302291.aspx#xinc_topic1

【问题讨论】:

  • 关于将 DTD 与您不直接创建的 XmlReader 一起使用的问题可能会对您有所帮助:stackoverflow.com/questions/1451704/…
  • 感谢您的链接。我实际上得到了一个几乎全部发布在下面的答案。我希望人们继续发布替代答案和建议。 XML 的世界非常广阔,当我试图将一些东西拼凑在一起时,几乎超出了我的口味。

标签: c# .net xml


【解决方案1】:

找到了使用 XMLReader 实例读取 XHTML 源代码的答案,该源代码包含命名实体,如   而不会抛出 XmlException

首先,我直接从 W3C 的页面复制了以下 XML 示例:XML Schema 中的 XHTML 1.0,1.5. Using DTD and XML Schema together 部分以支持引入命名实体字符并同时进行基于模式的验证:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"[
<!ATTLIST html
    xmlns:xsi CDATA #FIXED "http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation CDATA #IMPLIED
>
]>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.w3.org/1999/xhtml
                          http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd">
  ...
</html>

并且是 替换 XHTML 片段,例如&lt;body&gt;&lt;div&gt;&lt;b&gt;xhtml stuff&lt;/b&gt;&lt;/div&gt;&lt;/body&gt; 到上面示例中... 的位置。

这成功地将 DTD(引用命名实体)与架构验证混合在一起。遇到命名实体时,XMLReader 不再抛出 XMLExeption。
成功!


处理上述示例的C#.NET 代码

using System;
using System.IO;
using System.Xml;

核心逻辑如下。 注意:这是逐字复制和粘贴的。一些设置可能是轻率或多余的,因此您可以调整以实现其他各种里程。

XmlReaderSettings settingsXRdr = new XmlReaderSettings();
settingsXRdr.ProhibitDtd = false;
settingsXRdr.CheckCharacters = true;
settingsXRdr.ConformanceLevel = ConformanceLevel.Document;
settingsXRdr.IgnoreProcessingInstructions = false;
settingsXRdr.IgnoreComments = false;
settingsXRdr.XmlResolver = new CustomXmlResolver();
settingsXRdr.ValidationType = ValidationType.DTD;

// This is a format string; notice the placeholder {0} where the fragment will be injected:

string mixFmtString1 = @"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""[
<!ATTLIST html
xmlns:xsi CDATA #FIXED ""http://www.w3.org/2001/XMLSchema-instance""
xsi:schemaLocation CDATA #IMPLIED
>
]>
<html xmlns=""http://www.w3.org/1999/xhtml"" lang=""en"" xml:lang=""en""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xsi:schemaLocation=""http://www.w3.org/1999/xhtml
              http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd"">
<head><title></title></head>
<body>
<div>{0}</div>
</body>
</html>";


// Inject any well-formed fragment via the second argument
string xhtml = string.Format(mixFmtString1, "<b>Xhtml fragment w/named entity: &nbsp;</b>");

// Creates a validating reader (derived type) because of the above settings)
XmlReader rdr = XmlReader.Create(new StringReader(xhtml), settingsXRdr);

// Reads the entire XHTML document (validating it along the way).
while (rdr.Read()) {

    // Do whatever you want here for each piece processed.
    var dummy = rdr.NodeType.ToString();  // Access a string value for fun.
    // If you just want validation to occur then leave this an empty code block. 

}

注意:此解决方案对 XHTML 使用 Strict 模板,因此某些已弃用的标签(如 &lt;center&gt;)将使阅读器失败。您可能希望重新定义引用的项目以指向更宽容的loose XHTML template

沿途相关/有用的资源:

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    相关资源
    最近更新 更多