2009-06-05 5 views
10

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

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

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

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

Спасибо, Том

+0

Мы говорим с HTML или XML? –

+0

Зачем вам нужно анализировать HTML-код, который вы генерируете? Вам нужно будет иметь возможность вставлять встроенный HTML-код, который может быть недействительным? –

+0

Спасибо за ваши вопросы: mmyers: HTML Oliver: Извините, я не прояснил это. Если я правильно понимаю ваш вопрос, я создаю HTMLDocument (используя HTMLEditorKit # read) из HTML, который будет отображаться с помощью JTextPane. –

ответ

9

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

Это довольно простая библиотека, и она не изменилась целую вечность. Опять же, спецификация HTML 4.01 также не изменилась;) Я использовал ECS и считаю это намного лучше, чем создание больших фрагментов HTML с помощью только строк или 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; по крайней мере, я сделал, удивительно быстро.

+0

точно :-) +1 для скорости –

+1

Том не может использовать библиотеку напрямую (хотя почему у кого-то проблемы с лицензией Apache для меня загадка), но он может посмотреть на api для идей. –

+0

Хм, я уверен, что «я не могу прибегать к использованию каких-либо библиотек, кроме тех, которые были отправлены с JVM», не было в исходной версии вопроса! :) С этим ограничением JeeBee (утилитные классы, такие как TableBuilder) и решения Adam Paynter (XMLStreamWriter) кажутся разумными. – Jonik

1

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

PS: Вы считали какой-то шаблонный двигатель вроде freemarker?

+0

.. или скорость Apache? –

0

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

Или вы можете использовать один из существующих шаблонных двигателей для java-сервера на стороне сервера или скорости.

+0

Технически, HTML не является особым случаем XML. XHTML есть. –

+0

XHTML (выделение на X) - это XML. HTML - SGML. Они похожи, но на самом деле не то же самое. Наиболее допустимый XHTML также действителен HTML, но не все. –

+2

Поскольку он используется в JEditorPane, все, что нужно, это форма HTML, которую панель может читать. –

3

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

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

+1

+1 это самый быстрый, и мрачные аспекты могут быть спрятаны в классах строителей-утилит, как и в моем ответе также по этому вопросу. – JeeBee

7

Я бы посмотрел, как работают 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()); 
} 
+0

Я использовал TableBuilder здесь, потому что у меня был код, потому что нам нужно было встроить HTML-таблицу в электронные письма HTML в проекте. Это не так сложно писать, но вам нужно отслеживать открытые теги и текущее состояние. – JeeBee

2

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: Вы можете использовать свои любимые XML-файлы api и создавать XHTML.

4

Имея дело с XHTML, у меня был большой успех с использованием интерфейса Java 6 XMLStreamWriter.

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

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

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

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

0

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

например.

doc.insertBeforeEnd (элемент, html);

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

Смежные вопросы