有没有人知道如何在Java中以编程方式生成HTMLDocument对象而不需要在外部生成String然后使用HTMLEditorKit #read来解析它?我问的两个原因是:
首先,我的HTML生成例程需要非常快,我认为将字符串解析为内部模型比直接构建此模型更昂贵。
其次,面向对象的方法可能会产生更清晰的代码。
我还应该提一下,出于许可的原因,我不能使用除JVM附带的库之外的任何库。
谢谢, 汤姆
答案 0 :(得分:9)
一种面向对象的方法是使用名为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>
该库支持HTML 4.0和XHTML。最初困扰我的唯一事情很多是与XHTML版本相关的类的名称以小写字母开头:option
,input
,a
, tr
等等,这违反了最基本的Java约定。但是如果你想使用XHTML,你可以习惯这个;至少我这么做,出乎意料地快。
答案 1 :(得分:7)
我会研究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());
}
答案 2 :(得分: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();
答案 3 :(得分:3)
我认为通过类似StringBuilder(或直接到流)的方式手动生成HTML将是您的最佳选择,特别是如果您不能使用任何外部库。
无法使用任何外部库,您将在开发速度而非性能方面遭受更多损失。
答案 4 :(得分:2)
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。
答案 5 :(得分:1)
您可能希望使用render()方法构建一些Element对象,然后将它们组装在树结构中;通过访问algorhytm,您可以继续设置值,然后渲染整个事物。
PS:你考虑过像freemarker这样的模板引擎吗?
答案 6 :(得分:1)
您似乎可以使用HTMLDocument.BlockElement
和HTMLDocument.BlockElement
对象的直接构造来完成您尝试的操作。这些构造函数的签名表明至少可以直接使用。
我建议检查OpenJDK中的Swing源,看看解析器如何处理它,并从那里派生你的逻辑。
我还建议这种优化可能为时过早,如果这确实成为应用程序中的性能热点,那么这应该是速度优化的替代,用于更简单的方法(即生成HTML文本)。 / p>
答案 7 :(得分:0)
您可以使用任何体面的xml库,如JDom或Xom或XStream。 Html只是XML的一个特例。
或者,您可以将一个现有的模板引擎用于服务器端java,如jsp或velocity。
答案 8 :(得分:0)
基本上,您可以使用插入方法insertBeforeEnd(),insertAfterEnd(),insertBeforeStart(),insertAfterStart()之一将HTML插入HTMLDocument。 您为方法提供了要插入的html以及文档树中要插入html的位置。
例如
doc.insertBeforeEnd(element,html);
HTMLDocument类还提供了遍历文档树的方法。