将 HTML 插入 HTMLDocument 的正文

发布于 2024-09-14 02:39:55 字数 1353 浏览 6 评论 0原文

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

问题:

我有一些文本要插入到 HTMLDocument 中。该文本有时也会指定一些 html。 EG:

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

我正在使用 HTMLEditorKit.insertHTML 将其插入到指定的偏移量处。这工作正常,除非偏移量位于文档的开头(偏移量 = 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 我愿意接受这些想法 以及。

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

This seems like such a simple question, but I'm having such difficulty with it.

Problem:

I have some text to insert into an HTMLDocument. This text sometimes specifies some html as well. E.G.:

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

I'm using HTMLEditorKit.insertHTML to insert it at a specified offset. This works fine, unless the offset is at the begining of the doc (offset = 1). When this is the case the text gets inserted into the head of the document instead of the body.

Example:

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

I use the font tag so I now what I'm inserting will be in a font tag with no attributes so it won't effect the format. I need to know this because the last parameter, insertTag, is required and I can't know the contents of stringToInsert until runtime. If there is already text in the doc (such as "1234567890") then this is the output:

<html>
  <head>

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

However if the offset is 1 and the document is empty this is the result:

<html>
  <head>

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

Other Notes:

  • This is all being done on the
    innerdocument of a JEditorPane. If
    there is a better way to replace text
    in a JEditorPane with potential
    HTML I would be open to those ideas
    as well.

Any help would be appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╰◇生如夏花灿烂 2024-09-21 02:39:55

关于 HTMLDocument 的内部结构,您应该了解几件事。

  • 首先 - 正文不是从位置 0 开始。文档的所有文本内容都存储在 javax.swing.text.AbstractDocument$Content 的实例中。这还包括标题和脚本标签。任何文档和编辑器工具包功能的位置/偏移参数引用此 Content 实例中的文本!您必须确定正文元素的开头才能将内容正确插入正文中。顺便说一句:即使您没有在 HTML 中定义 body 元素,它也会由解析器自动生成。
  • 简单地插入某个位置往往会产生意想不到的副作用。您需要知道要将与此位置的 (HTML) 元素相关的内容放在哪里。例如,如果您的文档中有以下文本:“......” - 仅有一个位置(指内容实例)“在第一个跨度的末尾”、“在跨度之间”和“在第二个跨度的开始处”。为了解决这个问题,HTMLDocument API 中有 4 个函数:
    • 插入结束后
    • 开始后插入
    • 在结束前插入
    • 开始前插入

作为结论:对于通用解决方案,您必须找到 BODY 元素来告诉文档正文的“insertAfterStart”以及正文元素的起始偏移量。

以下片段在任何情况下都应该有效:

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 处插入始终有效。

There are several things you should know about the internal structure of the HTMLDocument.

  • First of all - the body does not start at position 0. All textual content of the document is stored in an instance of javax.swing.text.AbstractDocument$Content. This includes the title and script tags as well. The position/offset argument of ANY document and editor kit function refers to the text in this Content instance! You have to determine the start of the body element to correctly insert content into the body. BTW: Even though you didn't define a body element in your HTML, it will auto-generated by the parser.
  • Simply inserting at a position tends to have unexpected side effects. You need to know where you want to put the content in relation to the (HTML) elements at this position. E.g. if you have the following text in your document: "...</span><span>..." - there is only one position (referring to the Content instance) for "at the end of the first span", "between the spans" and "at the start of the second span". To solve this problem there are 4 functions in the HTMLDocument API:
    • insertAfterEnd
    • insertAfterStart
    • insertBeforeEnd
    • insertBeforeStart

As a conclusion: for a general solutions, you have to find the BODY element to tell the document to "insertAfterStart" of the body and at the start offset of the body element.

The following snipped should work in any case:

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>" );

If you're sure that the header is always empty, there is another way:

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

But this will throw a RuntimeException, if the header is not empty.

By the way, I prefer to use JWebEngine to handle and render HTML content since it keeps header and content separated, so inserting at position 0 always works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文