2010-09-17 25 views
6

tôi cần phải tải một số file xhtml có này ở đầu trang:Làm thế nào để tăng tốc độ tải DTD qua DOCTYPE

<?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"> 

Mỗi tập tin sẽ được nạp vào một System.Xml.XmlDocument riêng biệt. Do việc khai báo DOCTYPE nên chúng mất rất nhiều thời gian để tải. Tôi đã thử đặt XmlResolver = null, nhưng sau đó tôi nhận được XmlException bị ném vì tôi có các thực thể không hợp lệ (ví dụ: ”). Vì vậy, tôi nghĩ rằng tôi có thể tải xuống DTD chỉ cho XmlDocument đầu tiên và trong một số cách tái sử dụng nó cho XmlDocuments tiếp theo (và do đó tránh hiệu suất hit), nhưng tôi không có ý tưởng làm thế nào để làm điều này.

Tôi đang sử dụng .Net 3.5.

Cảm ơn.

Trả lời

4

Tôi nghĩ bạn có thể giải quyết vấn đề về trình giải quyết này bằng cách sử dụng XmlPreloadedResolver. Tuy nhiên, tôi đang gặp một số khó khăn khi làm việc đó. Có vẻ như XHTML 1.0 sẽ dễ dàng hơn để hỗ trợ vì nó là "DTD được biết": XmlKnownDtds trong khi XHTML 1.1 hiện không được "biết" nghĩa là bạn sẽ phải tải lại một loạt các URI.

Ví dụ:

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"); 
+0

Cảm ơn, nhưng XmlPreloadedResolver là Net 4 chỉ :-(Tôi đang trên 3.5. – Polyfun

+1

Bạn có thể tạo ra nguồn gốc của riêng bạn về 'XmlResolver' mà về cơ bản là giống nhau. –

+0

cảm ơn đây là những gì tôi đã làm, sử dụng ví dụ ở đây http://www.codeproject.com/KB/XML/HTML2XHTML.aspx? display = In. – Polyfun

1

Đối với .NET Framework 3.5 và dưới đây, nó có thể thực hiện được nếu sử dụng XmlUrlResolver, như thể hiện trong this answer. Tuy nhiên, cách tiếp cận này tải xuống các DTD từ trang web W3C trong thời gian chạy, đó không phải là một ý tưởng hay, ít nhất là vì W3C dường như hiện đang chặn các yêu cầu đó. Các other answer đề nghị bộ nhớ đệm các DTD như tài nguyên nhúng trong lắp ráp, tương tự như HTML2XHTML của bạn.

Đối với những người đọc khác sử dụng .NET Framework 4.0 trở lên, bạn có thể sử dụng XmlPreloadedResolver, như được đề xuất by Daniel Renshaw, hỗ trợ XHTML 1.0. Để hỗ trợ XHTML 1.1, bạn có thể đơn giản hóa việc triển khai của mình bằng cách sử dụng phiên bản DTD dẹt, có sẵn tại xhtml11-flat.dtd trên trang web W3C. Tôi xác định một phương pháp khuyến nông cho mục đích này:

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

này sau đó có thể được sử dụng như bình thường XmlResolver trường hợp:

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); 
Các vấn đề liên quan