java 将 HTML 插入到 HTMLDocument 的正文中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3470683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert HTML into the Body of an HTMLDocument
提问by Robbie
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.:
我有一些文本要插入到HTMLDocument. 该文本有时也会指定一些 html。例如:
Some <br />Random <b>HTML</b>
I'm using HTMLEditorKit.insertHTMLto 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 headof the document instead of the body.
我正在使用HTMLEditorKit.insertHTML它在指定的偏移量处插入它。这工作正常,除非偏移量位于文档的开头(偏移量 = 1)。在这种情况下,文本被插入到head文档的 中,而不是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 stringToInsertuntil runtime. If there is already text in the doc (such as "1234567890") then this is the output:
我使用字体标签,所以我现在插入的内容将位于没有属性的字体标签中,因此不会影响格式。我需要知道这一点,因为最后一个参数 ,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>
However if the offset is 1 and the document is empty this is the result:
但是,如果偏移量为 1 且文档为空,则结果为:
<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 aJEditorPanewith potential HTML I would be open to those ideas as well.
- 这一切都在
JEditorPane. 如果有更好的方法可以JEditorPane用潜在的 HTML替换 a 中的文本,我也会对这些想法持开放态度。
Any help would be appreciated. Thanks!
任何帮助,将不胜感激。 谢谢!
回答by tigger
There are several things you should know about the internal structure of the HTMLDocument.
关于 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
- 首先 - 正文不是从位置 0 开始的。文档的所有文本内容都存储在
javax.swing.text.AbstractDocument$Content. 这也包括标题和脚本标签。任何文档和编辑器工具包函数的位置/偏移量参数是指此 Content 实例中的文本!您必须确定 body 元素的开头才能将内容正确插入到正文中。顺便说一句:即使您没有在 HTML 中定义 body 元素,它也会由解析器自动生成。 - 简单地插入一个位置往往会产生意想不到的副作用。您需要知道要将与 (HTML) 元素相关的内容放在哪里。例如,如果您的文档中有以下文本:“
...</span><span>...” - 只有一个位置(指内容实例)用于“在第一个跨度的末尾”、“跨度之间”和“在第二个跨度的开始”跨度”。为了解决这个问题,HTMLDocument API 中有 4 个函数:- 插入后结束
- 开始后插入
- 在结束前插入
- 开始前插入
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.
作为结论:对于一般解决方案,您必须找到 BODY 元素来告诉文档主体的“insertAfterStart”和主体元素的起始偏移量。
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.
但是,如果标头不为空,这将引发 RuntimeException。
By the way, I prefer to use JWebEngineto handle and render HTML content since it keeps header and content separated, so inserting at position 0 always works.
顺便说一下,我更喜欢使用JWebEngine来处理和呈现 HTML 内容,因为它保持标题和内容分开,所以在位置 0 插入总是有效的。

