For the .NET Framework 3.5 and below, it might have been possible to use XmlUrlResolver , as shown in this answer . However, this approach downloads DTDs from the W3C website at run time, which is not a good idea, not least because the W3C seems to currently block such requests. another answer involves caching DTDs as embedded resources in an assembly, like your HTML2XHTML .
For other readers using the .NET Framework 4.0 and above, you can use XmlPreloadedResolver as suggested by Daniel Renshaw , who supports XHTML 1.0. To support XHTML 1.1, you can simplify your implementation by using the smoothed version of DTD available at xhtml11-flat.dtd on the W3C website. For this purpose, I define an extension method:
public static class XmlPreloadedResolverExtensions { private const string Xhtml11DtdPublicId = "-//W3C//DTD XHTML 1.1//EN"; private const string Xhtml11DtdSystemId = "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"; public static void AddXhtml11(this XmlPreloadedResolver resolver, bool @override = false) { Add(resolver, new Uri(Xhtml11DtdPublicId, UriKind.RelativeOrAbsolute), ManifestResources.xhtml11_flat_dtd, @override); Add(resolver, new Uri(Xhtml11DtdSystemId, UriKind.RelativeOrAbsolute), ManifestResources.xhtml11_flat_dtd, @override); } public static bool Add(this XmlPreloadedResolver resolver, Uri uri, Stream value, bool @override) { if (@override || !resolver.PreloadedUris.Contains(uri)) { resolver.Add(uri, value); return true; } return false; } }
Then it can be used as regular XmlResolver instances:
var xmlResolver = new XmlPreloadedResolver(); xmlResolver.AddXhtml11(); XmlReaderSettings settings = new XmlReaderSettings(); settings.DtdProcessing = DtdProcessing.Parse; settings.XmlResolver = xmlResolver; XDocument document; using (var xmlReader = XmlReader.Create(input, settings)) document = XDocument.Load(xmlReader);
Douglas
source share