Программная генерация HTMLDocument с использованием Java - PullRequest
11 голосов
/ 05 июня 2009

Кто-нибудь знает, как программно сгенерировать объект HTMLDocument в Java, не прибегая к генерации String извне, а затем используя HTMLEditorKit # read для его анализа? Две причины я спрашиваю:

Во-первых, моя процедура генерации HTML должна быть очень быстрой, и я предполагаю, что анализ строки во внутренней модели обходится дороже, чем непосредственное построение этой модели.

Во-вторых, объектно-ориентированный подход, вероятно, приведет к более чистому коду.

Я должен также отметить, что по причинам лицензирования я не могу прибегать к использованию каких-либо библиотек, кроме тех, которые поставляются с JVM.

Спасибо, Том

Ответы [ 9 ]

9 голосов
/ 05 июня 2009

Один объектно-ориентированный подход заключается в использовании библиотеки с именем ECS .

Это довольно простая библиотека, которая не менялась целую вечность. Опять же, спецификация HTML 4.01 также не изменилась;) Я использовал ECS и считаю, что это гораздо лучше, чем генерация больших фрагментов HTML с использованием только Strings или StringBuffers / StringBuilders.

Маленький пример:

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

optionElement.toString() теперь даст:

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

Библиотека поддерживает как HTML 4.0, так и XHTML. Единственное, что меня поначалу беспокоило много , это то, что имена классов, связанных с версией XHTML, начинались со строчной буквы: option, input, a, tr и т. Д. , что идет вразрез с самыми основными соглашениями Java. Но к этому можно привыкнуть, если вы хотите использовать XHTML; по крайней мере, я удивительно быстро.

7 голосов
/ 05 июня 2009

Я бы посмотрел на то, как работают JSP - то есть они компилируются в сервлет, который в основном представляет собой один длинный набор StringBuffer. Теги также компилируются в фрагменты кода Java. Это грязно, но очень и очень быстро, и вы никогда не увидите этот код, если не углубитесь в рабочий каталог Tomcat. Может быть, вам действительно нужно кодировать генерацию HTML из HTML-ориентированного представления, такого как JSP, с добавленными тегами для циклов и т. Д., И использовать аналогичный механизм генерации кода и компилятор внутри вашего проекта.

В качестве альтернативы, просто разберитесь с StringBuilder в служебном классе, который имеет методы для «openTag», «closeTag», «openTagWithAttributes», «startTable» и т. Д. ... он может использовать шаблон Builder код будет выглядеть так:

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());
}
4 голосов
/ 05 июня 2009

Имея дело с XHTML , я добился большого успеха, используя XMLStreamWriter интерфейс 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();
3 голосов
/ 05 июня 2009

Я думаю, что ручная генерация вашего HTML через что-то вроде StringBuilder (или напрямую в поток) будет вашим лучшим вариантом, особенно если вы не можете использовать какие-либо внешние библиотеки.

Не имея возможности использовать какие-либо внешние библиотеки, вы будете больше страдать с точки зрения скорости разработки, а не производительности.

2 голосов
/ 05 июня 2009

javax.swing.text.html имеет класс HTMLWriter и HTMLDocument среди других. Я не использовал их. Я использовал HtmlWriter в .Net , и он делает именно то, что вы хотите, но версия Java может не сработать.

Вот документация: http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/HTMLWriter.html

Кроме того, я не могу представить, чтобы StringBuilder был медленнее, чем здание с объектным слоем. Мне кажется, что любой объектно-ориентированный подход должен был бы построить граф объектов и затем создать строку. Основная причина не использовать необработанные строки для этого материала заключается в том, что вы наверняка получите ошибки кодирования, а также другие ошибки, приводящие к искаженным документам.

Вариант 2. Вы можете использовать ваши любимые API-интерфейсы XML и создавать XHTML.

1 голос
/ 05 июня 2009

Похоже, что вы можете выполнить то, что вы пытаетесь, используя прямое построение объектов HTMLDocument.BlockElement и HTMLDocument.BlockElement. Эти конструкторы имеют подпись, которая предполагает, что прямое использование возможно, по крайней мере.

Я бы предложил изучить исходные тексты Swing в OpenJDK, чтобы увидеть, как синтаксический анализатор справляется с этим, и извлечь из него вашу логику.

Я бы также предположил, что такая оптимизация может быть преждевременной, и, возможно, это должна быть оптимизированная по скорости замена более простого подхода (т. Е. Генерация текста HTML), который вводится только в том случае, если это действительно становится горячей точкой производительности в приложении. 1007 *

1 голос
/ 05 июня 2009

Возможно, вы захотите построить некоторый объект Element с помощью метода render (), а затем собрать их в древовидную структуру; с помощью алгоритма посещения вы можете приступить к установке значений, а затем отрисовать все целиком.

PS: вы рассматривали какой-нибудь шаблонизатор, как freemarker ?

0 голосов
/ 06 июня 2009

Обычно вы можете вставить html в ваш HTMLDocument, используя один из методов вставки: insertBeforeEnd (), insertAfterEnd (), insertBeforeStart (), insertAfterStart (). Вы предоставляете методу HTML-код, который хотите вставить, и позицию в дереве документа, к которой вы хотите добавить HTML-код.

например.

doc.insertBeforeEnd (element, html);

Класс HTMLDocument также предоставляет методы для обхода дерева документов.

0 голосов
/ 05 июня 2009

Вы можете использовать любую приличную библиотеку XML, такую ​​как JDom, Xom или XStream. Html - это особый случай XML.

Или вы можете использовать один из существующих шаблонизаторов для java на стороне сервера, например jsp или speed.

...