2009-06-05 9 views
10

Có ai biết cách tạo một đối tượng HTMLDocument theo lập trình trong Java mà không cần phải tạo một String bên ngoài và sau đó sử dụng HTMLEditorKit # read để phân tích cú pháp không? Hai lý do tôi yêu cầu:Tạo HTML tài liệu theo lập trình bằng cách sử dụng Java

Thứ nhất, quy trình tạo HTML của tôi cần rất nhanh và tôi giả định rằng phân tích chuỗi thành mô hình nội bộ tốn kém hơn so với xây dựng trực tiếp mô hình này.

Thứ hai, cách tiếp cận hướng đối tượng có thể dẫn đến mã sạch hơn.

Tôi cũng nên đề cập rằng, vì lý do cấp phép, tôi không thể sử dụng bất kỳ thư viện nào khác với các thư viện được vận chuyển với JVM.

Cảm ơn, Tom

+0

Chúng ta đang nói HTML hay XML? –

+0

Tại sao bạn cần phải phân tích cú pháp HTML mà bạn đang tạo ra? Bạn sẽ cần phải có thể chèn HTML nội tuyến có thể làm mất hiệu lực? –

+0

Cảm ơn câu hỏi của bạn: mmyers: HTML Oliver: Xin lỗi, tôi không nói rõ. Nếu tôi hiểu câu hỏi của bạn một cách chính xác, tôi đang tạo một HTMLDocument (sử dụng HTMLEditorKit # read) từ HTML để được kết xuất bởi một JTextPane. –

Trả lời

9

Một cách tiếp cận hướng đối tượng là sử dụng một thư viện gọi ECS.

Thư viện khá đơn giản và không thay đổi theo độ tuổi. Sau đó, một lần nữa, spec 4.01 HTML cũng không thay đổi;) Tôi đã sử dụng ECS ​​và xem xét nó tốt hơn nhiều so với việc tạo ra các đoạn HTML lớn chỉ với Strings hoặc StringBuffers/StringBuilders.

nhỏ ví dụ:

Option optionElement = new Option(); 
optionElement.setTagText("bar"); 
optionElement.setValue("foo"); 
optionElement.setSelected(false); 

optionElement.toString() sẽ hiện năng suất:

<option value='foo'>bar</option> 

Thư viện hỗ trợ cả HTML 4.0 và XHTML. Điều duy nhất ban đầu làm phiền tôi rất nhiều là tên của các lớp liên quan đến phiên bản XHTML bắt đầu bằng chữ thường: option, input, a, tr, v.v. Nhưng đó là điều bạn có thể quen với nếu bạn muốn sử dụng XHTML; ít nhất tôi đã làm, nhanh đến ngạc nhiên.

+0

chính xác :-) +1 cho tốc độ –

+1

Tom không thể sử dụng thư viện trực tiếp (mặc dù tại sao ai đó có vấn đề với giấy phép Apache là bí ẩn đối với tôi), nhưng anh ta có thể xem api cho ý tưởng. –

+0

Hmm, tôi khá chắc chắn rằng "Tôi không thể sử dụng bất kỳ thư viện nào khác ngoài những thư viện được vận chuyển với JVM" không có trong phiên bản gốc của câu hỏi! :) Với sự hạn chế đó, các lớp tiện ích như TableBuilder của JeeBee và Adam Paynter (XMLStreamWriter) có vẻ hợp lý. – Jonik

1

Bạn có thể muốn xây dựng một số đối tượng Element với phương thức render() và sau đó lắp ráp chúng trong một cấu trúc cây; với một algorhytm thăm bạn sau đó có thể tiến hành để thiết lập các giá trị và sau đó làm cho toàn bộ điều.

PS: bạn đã xem xét một số công cụ tạo mẫu như freemarker chưa?

+0

.. hoặc Apache Velocity? –

0

Bạn có thể sử dụng bất kỳ thư viện xml phong nha nào như JDom hoặc Xom hoặc XStream. Html chỉ là một trường hợp đặc biệt của XML.

Hoặc, bạn có thể sử dụng một trong các công cụ tạo khuôn mẫu hiện có cho phía máy chủ java như jsp hoặc vận tốc.

+0

Về mặt kỹ thuật, HTML không phải là trường hợp đặc biệt của XML. XHTML là. –

+0

XHTML (nhấn mạnh vào X) là XML. HTML là SGML. Chúng giống nhau nhưng không thực sự giống nhau. XHTML hợp lệ nhất cũng là HTML hợp lệ, nhưng không phải tất cả. –

+2

Vì nó đang được sử dụng trong một JEditorPane, tất cả nó cần phải là một dạng HTML mà ngăn có thể đọc. –

3

Tôi nghĩ rằng việc tạo HTML theo cách thủ công thông qua một thứ như StringBuilder (hoặc trực tiếp đến luồng) sẽ là lựa chọn tốt nhất, đặc biệt nếu bạn không thể sử dụng bất kỳ thư viện bên ngoài nào.

Không thể sử dụng bất kỳ thư viện bên ngoài nào, bạn sẽ phải chịu nhiều hơn về tốc độ phát triển hơn là hiệu suất.

+1

+1 nó là nhanh nhất, và các khía cạnh khó chịu có thể được ẩn đi trong các lớp xây dựng tiện ích, theo trả lời của tôi cũng về câu hỏi này. – JeeBee

7

Tôi sẽ xem xét cách thức hoạt động của JSP - tức là, chúng biên dịch thành một servlet về cơ bản là một phần lớn các phần nối thêm StringBuffer. Các thẻ cũng biên dịch thành đoạn mã Java. Điều này là lộn xộn, nhưng rất nhanh, và bạn không bao giờ thấy mã này trừ khi bạn đi sâu vào thư mục công việc của Tomcat.Có lẽ những gì bạn muốn là viết mã HTML của bạn từ một khung nhìn trung tâm HTML như một JSP, với các thẻ được thêm vào cho các vòng lặp, vv, và sử dụng một công cụ tạo mã tương tự và trình biên dịch nội bộ trong dự án của bạn. Ngoài ra, bạn chỉ cần xử lý StringBuilder trong lớp tiện ích có các phương thức cho "openTag", "closeTag", "openTagWithAttributes", "startTable", v.v ... nó có thể sử dụng mẫu Builder và mã của bạn sẽ trông như thế:

public static void main(String[] args) { 
    TableBuilder t = new TableBuilder(); 
    t.start().border(3).cellpadding(4).cellspacing(0).width("70%") 
     .startHead().style("font-weight: bold;") 
     .newRow().style("border: 2px 0px solid grey;") 
      .newHeaderCell().content("Header 1") 
      .newHeaderCell().colspan(2).content("Header 2") 
     .end() 
     .startBody() 
     .newRow() 
      .newCell().content("One/One") 
      .newCell().rowspan(2).content("One/Two") 
      .newCell().content("One/Three") 
     .newRow() 
      .newCell().content("Two/One") 
      .newCell().content("Two/Three") 
     .end() 
    .end(); 
    System.out.println(t.toHTML()); 
} 
+0

Tôi đã sử dụng một TableBuilder ở đây vì tôi đã có mã, bởi vì chúng tôi đã cần phải nhúng một bảng HTML vào các email HTML trong một dự án. Nó không phải là khó để viết, nhưng bạn cần phải theo dõi các thẻ mở và trạng thái hiện tại của bạn. – JeeBee

2

javax.swing.text.html có HTMLWriterHTMLDocument lớp số những người khác. Tôi đã không sử dụng chúng. Tôi đã sử dụng HtmlWriter trong .Net và nó thực hiện chính xác những gì bạn muốn, nhưng phiên bản java có thể không hoạt động như cũ.

Đây là doc: http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/HTMLWriter.html

Ngoài ra, tôi không thể tưởng tượng một StringBuilder là chậm hơn so với xây dựng với một lớp đối tượng. Dường như với tôi rằng mọi phương pháp tiếp cận hướng đối tượng sẽ phải xây dựng đồ thị đối tượng VÀ sau đó tạo ra chuỗi. Lý do chính không sử dụng chuỗi thô cho công cụ này là bạn chắc chắn sẽ gặp lỗi mã hóa cũng như các lỗi khác tạo ra tài liệu không đúng định dạng.

Tùy chọn 2: Bạn có thể sử dụng API yêu thích của bạn và tạo XHTML.

4

Khi giao dịch với XHTML, tôi đã có nhiều thành công khi sử dụng giao diện XMLStreamWriter của Java 6.

OutputStream destination = ...; 
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); 
XMLStreamWriter xml = outputFactory.createXMLStreamWriter(destination); 

xml.writeStartDocument(); 
xml.writeStartElement("html"); 
xml.writeDefaultNamespace("http://www.w3.org/1999/xhtml"); 

xml.writeStartElement("head"); 
xml.writeStartElement("title"); 
xml.writeCharacters("The title of the page"); 
xml.writeEndElement(); 
xml.writeEndElement(); 

xml.writeEndElement(); 
xml.writeEndDocument(); 
1

Dường như bạn có thể thực hiện những gì bạn đang cố gắng sử dụng xây dựng trực tiếp các đối tượng HTMLDocument.BlockElementHTMLDocument.BlockElement. Các nhà thầu xây dựng có một chữ ký cho thấy sử dụng trực tiếp là có thể, ít nhất.

Tôi sẽ đề nghị kiểm tra các nguồn Swing trong OpenJDK để xem cách trình phân tích cú pháp xử lý việc này và lấy logic của bạn từ đó. Tôi cũng khuyên rằng tối ưu hóa này có thể là quá sớm, và có lẽ đây phải là một sự thay thế tối ưu hóa tốc độ cho một cách tiếp cận đơn giản hơn (tức là tạo ra văn bản HTML) chỉ được giới thiệu nếu điều này thực sự trở thành điểm phát sóng hiệu năng trong ứng dụng.

0

Về cơ bản, bạn có thể chèn html vào HTMLDocument của mình bằng cách sử dụng một trong các phương thức chèn, insertBeforeEnd(), insertAfterEnd(), insertBeforeStart(), insertAfterStart(). Bạn cung cấp phương thức với html bạn muốn chèn và vị trí trong cây tài liệu mà bạn muốn chèn html.

ví dụ:

doc.insertBeforeEnd (phần tử, html);

Lớp HTMLDocument cũng cung cấp các phương thức để duyệt qua cây tài liệu.