使用Java生成程序化HTMLDocument

有没有人知道如何在Java中以编程方式生成HTMLDocument对象而不需要在外部生成String然后使用HTMLEditorKit #read来解析它? 我问的两个原因:

首先,我的HTML生成例程需要非常快,我认为将字符串解析为内部模型比直接构建此模型更昂贵。

其次,面向对象的方法可能会导致更清晰的代码。

我还应该提一下,出于许可的原因,我不能使用除JVM附带的库之外的任何库。

谢谢,汤姆

一种面向对象的方法是使用名为ECS的库。

这是一个非常简单的图书馆,并没有改变多年。 然后,HTML 4.01规范也没有改变;)我已经使用了ECS并且认为它比仅使用字符串或StringBuffers / StringBuilders生成大型HTML片段要好得多。

小例子:

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

optionElement.toString()现在会产生:

  

该库支持HTML 4.0和XHTML。 最初困扰我的唯一事情是,与XHTML版本相关的类的名称以小写字母开头: optioninputatr等,这违背了最基本的Java约定。 但是,如果你想使用XHTML,那就是你可以习惯的东西; 至少我做了,出乎意料地快。

我将研究JSP是如何工作的 – 也就是说,它们编译成一个基本上是一个庞大的StringBuffer追加组的servlet。 标签还可以编译成Java代码片段。 这很乱,但非常快,除非你深入研究Tomcat的工作目录,否则你永远不会看到这段代码。 也许你想要的是从像HTML这样的HTML中心视图中实际编写HTML生成代码,为循环添加标签等,并在项目内部使用类似的代码生成引擎和编译器。

或者,只需在一个实用程序类中处理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()); } 

在处理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(); 

我认为通过类似StringBuilder(或直接到流)的方式手动生成HTML将是您的最佳选择,特别是如果您不能使用任何外部库。

无法使用任何外部库,您将在开发速度而不是性能方面遭受更多损失。

javax.swing.text.html包含HTMLWriterHTMLDocument类。 我没有用过它们。 我在.Net中使用过HtmlWriter ,它完全符合你的要求,但java版本可能无法实现。

这是doc: http : //java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/HTMLWriter.html

此外,我无法想象StringBuilder比使用对象层构建要慢。 在我看来,任何面向对象的方法都必须构建对象图,然后生成字符串。 不使用原始字符串的主要原因是你肯定会遇到编码错误以及产生格式错误的文档的其他错误。

选项2:您可以使用自己喜欢的XML API并生成XHTML。

您可能希望使用render()方法构建一些Element对象,然后将它们组装在树结构中; 通过访问algorhytm,您可以继续设置值,然后渲染整个事物。

PS:你有没有想过像freemarker这样的模板引擎?

您似乎可以使用HTMLDocument.BlockElementHTMLDocument.BlockElement对象的直接构造来完成您尝试的操作。 这些构造函数有一个签名,建议至少可以直接使用。

我建议检查OpenJDK中的Swing源,看看解析器如何处理它,并从那里派生你的逻辑。

我还建议这种优化可能为时过早,如果这确实成为应用程序中的性能热点,那么这应该是速度优化的替代,用于更简单的方法(即生成HTML文本)。

您可以使用任何体面的xml库,如JDom或Xom或XStream。 Html只是XML的一个特例。

或者,您可以将一个现有的模板引擎用于服务器端java,如jsp或velocity。

基本上,您可以使用插入方法之一insertBeforeEnd(),insertAfterEnd(),insertBeforeStart(),insertAfterStart()将html插入HTMLDocument。 您为方法提供了要插入的html以及文档树中要插入html的位置。

例如。

doc.insertBeforeEnd(element,html);

HTMLDocument类还提供了遍历文档树的方法。