2009-08-17 8 views
12

Tôi đã tìm thấy một vài bài viết ám chỉ đến thực tế rằng bạn có thể xác nhận XHTML dựa vào DTD của nó bằng cách sử dụng đá quý nokogiri. Trong khi tôi đã quản lý để sử dụng nó để phân tích XHTML thành công (tìm kiếm 'một' thẻ vv), tôi đang đấu tranh để xác nhận tài liệu.Làm cách nào để xác thực XHTML bằng nokogiri?

Đối với tôi, điều này:

doc = Nokogiri::XML(Net::HTTP.get(URI.parse("http://www.w3.org"))) 
puts doc.validate 

kết quả trong một đống toàn bộ:

[ 
#<Nokogiri::XML::SyntaxError: No declaration for element html>, 
#<Nokogiri::XML::SyntaxError: No declaration for attribute xmlns of element html>, 
#<Nokogiri::XML::SyntaxError: No declaration for attribute lang of element html>, 
#<Nokogiri::XML::SyntaxError: No declaration for attribute lang of element html>, 
#<Nokogiri::XML::SyntaxError: No declaration for element head>, 
#<Nokogiri::XML::SyntaxError: No declaration for attribute profile of element head 
[repeat for every tag in the document.] 
] 

Vì vậy, tôi giả định đó không phải là cách tiếp cận đúng. Tôi dường như không thể tìm ra bất kỳ ví dụ hay nào - có ai có thể gợi ý tôi đang làm gì sai không?

Tôi đang chạy ruby ​​1.8.6 trên Mac OSX 10.5.8. Nokogiri nói với tôi:

nokogiri: 1.3.3 
warnings: [] 

libxml: 
    compiled: 2.6.23 
    loaded: 2.6.23 
    binding: extension 

Trả lời

14

Đó không chỉ là bạn. Những gì bạn đang làm được cho là đúng cách để làm điều đó, nhưng tôi chưa bao giờ có may mắn với nó. Theo như tôi có thể nói, có một số ngắt kết nối một nơi nào đó giữa Nokogiri và libxml mà làm cho nó không tải SYSTEM DTDs, hoặc để nhận ra PUBLIC DTD. Nó sẽ hoạt động nếu bạn xác định DTD trong tệp XML, nhưng may mắn làm điều đó với các DTD XHTML.

Điều tốt nhất tôi có thể đề nghị là sử dụng schemas for XHTML thay vì:

require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::XML(open('http://www.w3.org')) 
xsd = Nokogiri::XML::Schema(open('http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd')) 

#this is a true/false validation 
xsd.valid?(doc) # => true 

#this gives a listing of errors 
xsd.validate(doc) # => [] 
+0

Đó là tuyệt vời - nó chắc chắn sản xuất hợp lý tôi nhìn kết quả (trong nháy mắt!). Mặc dù, một cách kỳ quặc, một số trang tôi đang xác thực các ngăn xếp sản phẩm của các cảnh báo "Unimplemented block at xmlschemas.c: 27443" - nhưng sau đó tiến hành báo cáo chúng hợp lệ không có lỗi. Tôi đã không có để dưới cùng của mô hình của những người thân và không phải là vào thời điểm này. – NeilS

1

Nó hoạt động ok nếu DTD được nhúng trong XML. Vì vậy, nếu cơ cấu lại dữ liệu trong một tệp duy nhất là ok, hoặc là một thực hành chung, hoặc chỉ để sử dụng tạm thời, có thể giải quyết vấn đề của bạn.

tôi nộp một vấn đề với các dự án Nokogiri tại địa chỉ:

https://github.com/sparklemotion/nokogiri/issues/440

Yoko Harada, tác giả chính của JRuby Nokigiri, cho biết:

"Just FYI tinh khiết Java Nokogiri trên chi nhánh tổng thể (không. chưa phát hành) không có vấn đề này. "

Vấn đề tôi đã gửi chứa liên kết đến các tệp mẫu tối thiểu và các cuộc gọi irb để minh họa sự cố.

  • Keith