2008-11-19 19 views
11

XML của tôi (a.xhtml) bắt đầu như thế nàyLàm cách nào để ngăn chặn XML :: XPath tìm nạp DTD trong khi xử lý tệp XML?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
... 

Mã của tôi bắt đầu như thế này

use XML::XPath; 

use XML::XPath::XMLParser; 

my $xp = XML::XPath->new(filename => "a.xhtml"); 

my $nodeset = $xp->find('/html/body//table'); 

Nó rất chậm, và nó chỉ ra rằng nó dành rất nhiều thời gian nhận được DTD (http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd).

Có cách nào để khai báo một cách rõ ràng máy chủ proxy HTTP trong họ Perl XML :: không? Tôi ghét sửa đổi tài liệu gốc a.xhtml như có bản sao cục bộ của DTD.

Trả lời

14

XML :: XPath dựa trên XML :: Trình phân tích cú pháp. Có một tùy chọn trong XML :: Parser để KHÔNG sử dụng LWP để giải quyết các thực thể bên ngoài (như các DTD). Và XML :: XPath cho phép bạn chuyển một XML :: Parser objetc, để sử dụng làm trình phân tích cú pháp.

Vì vậy, bạn có thể viết này:

my $p = XML::Parser->new(NoLWP => 1); 
my $xp= XML::XPath->new(parser => $p, filename => "a.xhtml"); 

Lưu ý rằng trong trường hợp này bạn sẽ mất tất cả các đơn vị ngoại trừ những số và những người mặc định (>, <, &, ' và "). Trình phân tích cú pháp sẽ không phàn nàn, nhưng chúng sẽ biến mất một cách âm thầm (thử bao gồm & alpha; trong bảng và in nó chẳng hạn).

Thực tế bạn có lẽ không nên sử dụng XML :: XPath, không được duy trì tích cực.

Hãy thử XML :: LibXML, nếu bạn không có vấn đề với cài đặt libxml2, giao diện của nó rất giống với XML :: XPath khi cả hai đều triển khai DOM. XML :: LibXML cũng mạnh hơn nhiều so với XML :: XPath và khởi động nhanh hơn. Nếu bạn muốn một mô đun dựa trên người nước ngoài/XML :: Parser, họ có thể muốn xem xét XML :: Twig (đó là tự quảng cáo trắng trợn vì tôi là tác giả của mô-đun, xin lỗi). Cũng cho HTML/dodgy XHTML, bạn có thể sử dụng HTML :: TreeBuilder, trong đó, với việc bổ sung HTML :: TreeBuilder :: XPath (cũng bởi tôi), hỗ trợ XPath.

1

Thông thường nó được thực hiện bằng cách thiết lập địa phương XML catalog.

trình phân tích dựa trên libxml hỗ trợ nó, vì vậy nếu bạn làm theo lời khuyên của mirod, bạn sẽ có thể nhận được các thực thể có tên và công việc xác thực mà không cần truy cập mạng.

+0

Đúng. Bạn có thể sử dụng XML :: Catalog để thêm một danh mục vào một đối tượng XML :: Parser và sử dụng trình phân tích cú pháp đó trong XML :: mới của XPath. Tôi chưa bao giờ thử nghiệm điều đó. – mirod

3

phản hồi của pornL có vẻ là Điều đúng ở đây. (www.w3.org đã bắt đầu mất 30 giây để trả lời từng truy vấn của tôi (khi nó không chỉ từ bỏ), và khi XML :: XPath kết thúc việc lấy toàn bộ tập XHTML & hellip;!) Hơn nữa, ý tưởng của mirod hoạt động , quá:

use XML::XPath; 
use XML::Catalog; 

my $parser = new XML::Parser; 
my $catalog_handler = new XML::Catalog("xhtml1-20020801/DTD/xhtml.soc")->get_handler($parser); 
$parser->setHandlers("ExternEnt" => $catalog_handler); 
my $xp = new XML::XPath(xml => $xml, parser => $parser); 

Thêm một bản sao của "The bộ hoàn chỉnh các DTD tập tin cùng với một khai báo XML và SGML mở Catalog" từ ⟨ URL: http://www.w3.org/TR/xhtml1/dtds.html ⟩ và tận hưởng!

Các vấn đề liên quan