代码之家  ›  专栏  ›  技术社区  ›  Polyfun MicBehrens

如何通过DOCTYPE加速DTD的加载

  •  6
  • Polyfun MicBehrens  · 技术社区  · 14 年前

    我需要加载一些顶部有以下内容的xhtml文件:

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    

    我正在使用.NET3.5。

    谢谢。

    2 回复  |  直到 14 年前
        1
  •  5
  •   Daniel Renshaw    14 年前

    我认为您应该能够使用 XmlPreloadedResolver XmlKnownDtds

    例如:

    XmlPreloadedResolver xmlPreloadedResolver = new XmlPreloadedResolver(XmlKnownDtds.Xhtml10);
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"), File.ReadAllBytes("D:\\xhtml11.dtd"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstyle-1.mod"), File.ReadAllBytes("D:\\xhtml-inlstyle-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-framework-1.mod"), File.ReadAllBytes("D:\\xhtml-framework-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod"), File.ReadAllBytes("D:\\xhtml-text-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod"), File.ReadAllBytes("D:\\xhtml-hypertext-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod"), File.ReadAllBytes("D:\\xhtml-list-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-edit-1.mod"), File.ReadAllBytes("D:\\xhtml-edit-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-bdo-1.mod"), File.ReadAllBytes("D:\\xhtml-bdo-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/ruby/xhtml-ruby-1.mod"), File.ReadAllBytes("D:\\xhtml-ruby-1.mod"));
    xmlPreloadedResolver.Add(new Uri("http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-pres-1.mod"), File.ReadAllBytes("D:\\xhtml-pres-1.mod"));
    // TODO: Add other modules here (see the xhtml11.dtd for the full list)
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.XmlResolver = xmlPreloadedResolver;
    xmlDocument.Load("D:\\doc1.xml");
    
        2
  •  1
  •   Community Erin Dees    7 年前

    对于.NETFramework3.5及更低版本,可以使用 XmlUrlResolver ,如中所示 this answer . 然而,这种方法在运行时从W3C网站下载dtd,这不是一个好主意,尤其是因为W3C似乎正在阻止这样的请求。这个 other answer HTML2XHTML .

    对于其他使用.NETFramework4.0及更高版本的读者,您可以使用 XmlPreloadedResolver ,如建议 by Daniel Renshaw ,它支持XHTML1.0。为了支持XHTML1.1,您可以通过使用DTD的扁平化版本来简化实现 xhtml11-flat.dtd 在W3C网站上。我为此定义了一个扩展方法:

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

    这样就可以像平常一样使用了 XmlResolver

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