加载到XDocument时如何解析实体?

我正在尝试将XHTML文档加载到XDocument中,但我得到了“对未声明的实体的引用”exception抛出。 我需要解决像®这样的实体®»

我相信我的文件是正确形成的,这是头部:

    

当我执行XDocument.Load()时,我正在抛出这些exception。

这是msdn和博客post的合作。

  XDocument document; using (var stringReader = new StringReader(output)) { var settings = new XmlReaderSettings { ProhibitDtd = false, XmlResolver = new LocalXhtmlXmlResolver(bool.Parse(ConfigurationManager.AppSettings["CacheDTDs"])) }; document = XDocument.Load(XmlReader.Create(stringReader, settings)); } private class LocalXhtmlXmlResolver : XmlUrlResolver { private static readonly Dictionary KnownUris = new Dictionary { { "-//W3C//DTD XHTML 1.0 Strict//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") }, { "-//W3C XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") }, { "-//W3C//DTD XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") }, { "-//W3C XHTML 1.0 Frameset//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd") }, { "-//W3C//DTD XHTML 1.1//EN", new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd") } }; private bool enableHttpCaching; private ICredentials credentials; public LocalXhtmlXmlResolver(bool enableHttpCaching) { this.enableHttpCaching = enableHttpCaching; } public override Uri ResolveUri(Uri baseUri, string relativeUri) { Debug.WriteLineIf(!KnownUris.ContainsKey(relativeUri), "Could not find: " + relativeUri); return KnownUris.ContainsKey(relativeUri) ? KnownUris[relativeUri] : base.ResolveUri(baseUri, relativeUri); } public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { if (absoluteUri == null) { throw new ArgumentNullException("absoluteUri"); } //resolve resources from cache (if possible) if (absoluteUri.Scheme == "http" && this.enableHttpCaching && (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream))) { var request = WebRequest.Create(absoluteUri); request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default); if (this.credentials != null) { request.Credentials = this.credentials; } var response = request.GetResponse(); return response.GetResponseStream(); } //otherwise use the default behavior of the XmlUrlResolver class (resolve resources from source) return base.GetEntity(absoluteUri, role, ofObjectToReturn); } } 

我遇到了与Dave相同的问题,并且遇到了这个帮助我很多的问题。 根据Dave的回答和Pavel的优化建议,我更新了课程。 现在,DTD可以存储为嵌入式资源,并在必要时加载。 我知道这篇文章已经有几年了但也许这可以帮助别人。

用法示例:

 XmlReaderSettings readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, XmlResolver = new LocalXhtmlXmlResolver() }; using (XmlReader reader = XmlReader.Create(xhtmlStream, readerSettings)) { XDocument xhtml = XDocument.Load(reader); ... } 

LocalXhtmlXmlResolver类:

 public class LocalXhtmlXmlResolver : XmlUrlResolver { private const string ResourcePrefix = "Your.Namespace.Here."; private static readonly Dictionary _knownDtds = new Dictionary { { "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", ResourcePrefix + "xhtml1-strict.dtd" }, { "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", ResourcePrefix + "xhtml1-transitional.dtd" }, { "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd", ResourcePrefix + "xhtml1-frameset.dtd" }, { "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd", ResourcePrefix + "xhtml11.dtd" }, { "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Latin 1 for XHTML//EN", ResourcePrefix + "xhtml-lat1.ent" }, { "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Special for XHTML//EN", ResourcePrefix + "xhtml-special.ent" }, { "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Symbols for XHTML//EN", ResourcePrefix + "xhtml-symbol.ent" } }; private static readonly Dictionary _knownUris = new Dictionary { { "-//W3C//DTD XHTML 1.0 Strict//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") }, { "-//W3C XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") }, { "-//W3C//DTD XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") }, { "-//W3C XHTML 1.0 Frameset//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd") }, { "-//W3C//DTD XHTML 1.1//EN", new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd") } }; public override Uri ResolveUri(Uri baseUri, string relativeUri) { return _knownUris.ContainsKey(relativeUri) ? _knownUris[relativeUri] : base.ResolveUri(baseUri, relativeUri); } public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { if (absoluteUri == null) { throw new ArgumentNullException("absoluteUri"); } if (_knownDtds.ContainsKey(absoluteUri.OriginalString)) { string resourceName = _knownDtds[absoluteUri.OriginalString]; Assembly assembly = Assembly.GetAssembly(typeof(LocalXhtmlXmlResolver)); return assembly.GetManifestResourceStream(resourceName); } return base.GetEntity(absoluteUri, role, ofObjectToReturn); } }