有没有人知道如何在Java中以编程方式生成HTMLDocument对象,而不是借助于外部生成字符串,然后使用HTMLEditorKit#read进行解析?我提出这个问题有两个原因:
首先,我的HTML生成例程需要非常快速,我认为将字符串解析为内部模型比直接构建此模型更加昂贵。
其次,面向对象的方法可能会导致更清晰的代码。
我还应该提到,基于许可证原因,我不能使用除JVM附带库之外的任何库。
有没有人知道如何在Java中以编程方式生成HTMLDocument对象,而不是借助于外部生成字符串,然后使用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()
现在将产生以下结果:
<option value='foo'>bar</option>
option
、input
、a
、tr
等等,这违反了大多数Java基本约定。但如果你想使用XHTML,你可以适应它; 我惊讶地发现我很快就习惯了。我建议您学习一下JSP的工作原理,即它们编译成一个基本上是一系列StringBuffer append的servlet。标签也会编译成Java代码片段。这很混乱,但非常非常快,除非您深入Tomcat的工作目录,否则您永远看不到这些代码。也许您想要的是像JSP那样从HTML为中心的视角编写您的HTML生成,添加循环等标签,并在项目内部使用类似的代码生成引擎和编译器。
或者,您可以自己处理StringBuilder,在一个实用程序类中拥有“openTag”,“closeTag”,“openTagWithAttributes”,“startTable”等方法……它可以使用构建器模式,您的代码将如下所示:
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中包含了HTMLWriter和HTMLDocument等类。我没有使用过它们。我在.Net中使用了HtmlWriter,它可以完全满足您的需求,但是Java版本可能不会完全相同。
这是文档:http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/HTMLWriter.html
此外,我无法想象StringBuilder比对象层次结构构建更慢。在我看来,任何面向对象的方法都必须构建对象图,然后生成字符串。不使用原始字符串的主要原因是会产生编码错误以及其他导致文档格式不正确的错误。
选项2:您可以使用您喜欢的XML api并生成XHTML。
看起来您可以通过直接构建 HTMLDocument.BlockElement
和 HTMLDocument.BlockElement
对象来完成您正在尝试的操作。这些构造函数的签名表明直接使用是可能的,至少如此。
我建议您检查OpenJDK中Swing源代码的处理方式,并从中推导出您的逻辑。
我还建议,如果这确实成为应用程序中的性能热点,那么这种优化可能是过早的,也许应该将其作为一个简单方法(即生成HTML文本)的速度优化替代方案。
你可以使用任何像JDom、Xom或XStream这样的良好的XML库。HTML只是XML的一个特例。
或者,你可以使用现有的服务器端Java模板引擎之一,如JSP或Velocity。
基本上,您可以使用其中一种插入方法(insertBeforeEnd(),insertAfterEnd(),insertBeforeStart(),insertAfterStart())将HTML插入到HTMLDocument中。您提供要插入的html和要插入html的文档树中的位置。
例如:
doc.insertBeforeEnd(element,html);
HTMLDocument类还提供了遍历文档树的方法。