将HTML插入HTMLDocument的正文中

时间:2010-08-12 18:12:34

标签: java html jeditorpane htmleditorkit

这似乎是一个如此简单的问题,但我遇到了这样的困难。

问题:

我有一些文字要插入HTMLDocument。这个文本有时也会指定一些html。 E.G:

Some <br />Random <b>HTML</b>

我正在使用HTMLEditorKit.insertHTML将其插入指定的偏移量。这工作正常,除非偏移量在doc的开头(offset = 1)。在这种情况下,文本会插入到文档的head而不是body

实施例

editorKitInstance.insertHTML(doc, offset, "<font>"+stringToInsert+"</font>", 0, 0, HTML.Tag.FONT);

我使用字体标记,所以我现在插入的内容将是一个没有属性的字体标记,因此它不会影响格式。我需要知道这一点,因为最后一个参数insertTag是必需的,直到运行时我才能知道stringToInsert的内容。如果文档中已有文本(例如“1234567890”),那么这就是输出:

<html>
  <head>

  </head>
  <body>
    <p style="margin-top: 0">
      1234567890 <font>something <br />Some <br />Random <b>HTML</b></font>
    </p>
  </body>
</html>

但是,如果偏移量为1且文档为空,则结果为:

<html>
  <head>

<font>Some <br />Random <b>HTML</b></font>
  </head>
  <body>
  </body>
</html>

其他注释:

  • 这一切都是在 JEditorPane的内部文档。如果 有一种更好的方法来替换文本 在具有潜力的JEditorPane中 HTML我会接受这些想法 同样。

任何帮助将不胜感激。的谢谢!

1 个答案:

答案 0 :(得分:6)

关于HTMLDocument的内部结构,您应该了解一些事项。

  • 首先 - 正文不会从位置0开始。文档的所有文本内容都存储在javax.swing.text.AbstractDocument$Content的实例中。这也包括标题和脚本标记。 ANY文档和编辑器工具包函数的位置/偏移量参数是指此Content实例中的文本!您必须确定body元素的开头以正确地将内容插入到正文中。顺便说一句:即使你没有在HTML中定义一个body元素,它也会由解析器自动生成。
  • 简单地插入位置往往会产生意想不到的副作用。您需要知道要将内容与此位置的(HTML)元素相关联的位置。例如。如果您的文档中包含以下文本:“...</span><span>...” - “第一个跨度结束时”,“跨度之间”和“之间只有一个位置(指内容实例)”第二个跨度的开始“。要解决此问题,HTMLDocument API中有4个函数:
    • insertAfterEnd
    • insertAfterStart
    • insertBeforeEnd
    • insertBeforeStart

作为结论:对于一般解决方案,您必须找到BODY元素,以告知文档正文的“insertAfterStart”和body元素的起始偏移量。

以下剪辑应该适用于任何情况:

HTMLDocument htmlDoc = ...;
Element[] roots = htmlDoc.getRootElements(); // #0 is the HTML element, #1 the bidi-root
Element body = null;
for( int i = 0; i < roots[0].getElementCount(); i++ ) {
    Element element = roots[0].getElement( i );
    if( element.getAttributes().getAttribute( StyleConstants.NameAttribute ) == HTML.Tag.BODY ) {
        body = element;
        break;
    }
}
htmlDoc.insertAfterStart( body, "<font>text</font>" );

如果您确定标题始终为空,则还有另一种方法:

kit.read( new StringReader( "<font>test</font>" ), htmlDoc, 1 );

但如果标题不为空,则会抛出RuntimeException。

顺便说一句,我更喜欢使用JWebEngine来处理和呈现HTML内容,因为它保持标题和内容分离,因此在位置0插入始终有效。