C# 使用XmlReader时引用外部命名字符实体?

C# 使用XmlReader时引用外部命名字符实体?,c#,.net,xml,C#,.net,Xml,我想引用一个URL,该URL在实例上使用C#/.NET具有字符实体,例如定义和其他字符 如果我要用纯XML实现它,它可能是这样的,或者是一种变体: 实际上,我正在读取XHTML源代码(包含命名实体)的片段,因此需要定义/识别XML 1.0/命名。 (我在问如何在设置XmlReader及其读取片段的设置时动态地以编程方式引用它们;但是我对选项持开放态度) 无论哪种方式,如果我不包括这些命名实体,读者将咳嗽并产生.NET错误,例如和其他非数字实体的以下XmlException: 测试“Xml\u

我想引用一个URL,该URL在实例上使用C#/.NET具有字符实体,例如定义
和其他字符

如果我要用纯XML实现它,它可能是这样的,或者是一种变体:

实际上,我正在读取XHTML源代码(包含命名实体)的片段,因此需要定义/识别XML 1.0/命名。
(我在问如何在设置XmlReader及其读取片段的设置时动态地以编程方式引用它们;但是我对选项持开放态度)

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

测试“Xml\u Tester.Test\u Reading”失败: System.Xml.XmlException:参考 未声明的实体“nbsp”。第6行, 第393位

注意:我正在使用collection属性成功地引用一个实体,并假设必须有一种同样简单的方法来调用外部实体引用,而无需修改XML源,但它回避了我


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

对实体的支持
要使用实体,作者必须使用DTD机制。请参见第1.5节,以将DTD和XML模式一起使用。 --

1.5。同时使用DTD和XML模式
DTD验证和XML模式验证不是相互排斥的。有时,作者可能希望在利用XML模式验证的同时使用一些DTD特性(例如实体)。 --

将XML文档与XInclude相结合
外部实体必须在DTD或内部子集中声明。这打开了一个充满含义的潘多拉盒子,例如文档元素必须在Doctype声明中命名,验证读者可能需要在DTD中定义文档的完整内容模型等。

--

找到了使用XMLReader实例读取包含命名实体(如
)的XHTML源代码的答案,而不引发XmlException

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

<!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>
核心逻辑如下注意:这是逐字复制和粘贴的。一些设置可能是琐碎的或多余的,因此您可以调整以实现其他各种里程数

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. 

}
XmlReaderSettings设置XRDR=new XmlReaderSettings();
setingsxrdr.ProhibitDtd=false;
settingsXRdr.CheckCharacters=true;
settingsXRdr.ConformanceLevel=ConformanceLevel.Document;
settingsXRdr.IgnoreProcessingInstructions=false;
settingsXRdr.IgnoreComments=false;
settingsXRdr.XmlResolver=新的CustomXmlResolver();
settingsXRdr.ValidationType=ValidationType.DTD;
//这是一个格式字符串;请注意将插入片段的占位符{0}:
字符串mixFmtString1=@”
{0}
";
//通过第二个参数注入任何格式良好的片段
string xhtml=string.Format(mixFmtString1,“带有命名实体的xhtml片段:”;
//由于上述设置,创建验证读取器(派生类型)
XmlReader rdr=XmlReader.Create(新的StringReader(xhtml),设置XHRDR);
//读取整个XHTML文档(在此过程中对其进行验证)。
while(rdr.Read()){
//在这里为每件加工好的产品做任何你想做的事情。
var dummy=rdr.NodeType.ToString();//为了好玩而访问字符串值。
//如果您只是想进行验证,那么将其保留为空代码块。
}
注意:此解决方案使用XHTML的严格模板,因此某些不推荐使用的标记(如
)将使读取器失败。您可能希望重新格式化引用的项目,以指向更宽容的项目

沿途提供的相关/有用资源:

  • 类似的问题,以不同的方式解决:

我关于将DTD与您不直接创建的XmlReader一起使用的问题可能会对您有所帮助:谢谢您的链接。事实上,我得到了一个答案,这个答案几乎全部贴在了下面。我希望人们继续发布备选答案和建议。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. 

}