Vì các tệp HTML thường có vấn đề, trước tiên bạn cần dọn dẹp chúng bằng trình phân tích cú pháp/máy quét. Tôi đã sử dụng JTidy nhưng không bao giờ vui vẻ. NekoHTML hoạt động tốt, nhưng bất kỳ công cụ nào trong số này luôn luôn chỉ là một dự đoán tốt nhất về những gì được dự định. Bạn có hiệu quả yêu cầu để cho một chương trình thay đổi đánh dấu của tài liệu cho đến khi nó phù hợp với một lược đồ. Điều đó có thể sẽ gây ra kết cấu (đánh dấu), kiểu hoặc mất nội dung. Nó là không thể tránh khỏi, và bạn sẽ không thực sự biết những gì còn thiếu, trừ khi bạn quét bằng tay thông qua một trình duyệt (và sau đó bạn phải tin tưởng trình duyệt quá).
Nó thực sự phụ thuộc vào mục đích của bạn — nếu bạn có hàng nghìn tài liệu xấu với hàng tấn không liên quan (không phải HTML), thì quy trình thủ công có thể không hợp lý. Nếu mục tiêu của bạn là chính xác trên một vài tài liệu quan trọng, thì việc khắc phục thủ công chúng là một đề xuất hợp lý.
Một cách tiếp cận là quy trình thủ công liên tục chuyển nguồn qua trình phân tích cú pháp được xác định và/hoặc xác thực, trong một chu kỳ chỉnh sửa bằng cách sử dụng các thông báo lỗi để cuối cùng sửa chữa đánh dấu bị hỏng. Điều này đòi hỏi một số hiểu biết về XML, nhưng đó không phải là một giáo dục xấu để thực hiện.
Với Java 5 các tính năng XML cần thiết — được gọi là API JAXP — hiện được tích hợp vào chính Java; bạn không cần bất kỳ thư viện bên ngoài nào.
Lần đầu tiên bạn có được một thể hiện của một DocumentBuilderFactory, thiết lập các tính năng của nó, tạo một DocumentBuilder (trình phân tích cú pháp), sau đó gọi phương thức parse() của nó với một InputSource. InputSource có một số nhà thầu có thể, với một StringReader được sử dụng trong ví dụ sau:
import javax.xml.parsers.*;
// ...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(true);
dbf.setIgnoringComments(false);
dbf.setIgnoringElementContentWhitespace(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
return db.parse(new InputSource(new StringReader(source)));
Điều này trả về một tài liệu DOM. Nếu bạn không nhớ sử dụng các thư viện bên ngoài thì cũng có các API JDOM và XOM, và trong khi chúng có một số ưu điểm so với SAX và các API DOM trong JAXP, chúng yêu cầu phải thêm các thư viện không phải Java. DOM có thể hơi cồng kềnh, nhưng sau nhiều năm sử dụng nó, tôi không thực sự bận tâm nữa.
Neko + Xerces thực hiện công việc khá tốt. Cảm ơn tất cả các câu trả lời –
Hãy coi chừng JTidy. Nó có một lỗi rò rỉ bộ nhớ.Nếu bạn chạy nó trong một hệ thống sản xuất thì cuối cùng nó sẽ nổ tung - StackOverflowError và cuối cùng là OutOfMemoryError. Điều đó nói rằng, nó là tuyệt vời tốt lúc sửa chữa html bị hỏng để bạn có thể ăn nó vào một phân tích cú pháp dom. – Joel
Có cách nào tốt để sử dụng JTidy làm giao diện người dùng cho JDOM hoặc XOM theo kiểu truyền trực tiếp không? Đó là, mà không đọc toàn bộ tài liệu vào bộ nhớ đầu tiên? (Và không sử dụng PipedInput/OutputStream và nhiều chủ đề?) Hoặc tôi sẽ tốt hơn hết chỉ bằng cách sử dụng Neko trong trường hợp đó? –