How do I resolve entities when loading into an XDocument?

后端 未结 2 1776
死守一世寂寞
死守一世寂寞 2020-12-01 19:24

I\'m trying to load an XHTML document into an XDocument but I\'m getting \"reference to undeclared entity\" exceptions thrown at me. I need to resolve entities like &a

2条回答
  •  攒了一身酷
    2020-12-01 19:55

    This is a collaboration of msdn and blog postings.

            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);
            }
        }
    

提交回复
热议问题