gpt4 book ai didi

java - HTMLDocument 文本中位置或偏移量的含义

转载 作者:技术小花猫 更新时间:2023-10-29 12:42:13 26 4
gpt4 key购买 nike

我试图了解位置/偏移量在 HTMLDocument 中的工作原理。描述了位置/偏移语义 here .我的解释是,这些是由 HTMLDocument 表示的屏幕字符序列中的索引。

考虑来自 the HTMLDocument documentation 的示例 HTML :

 <html>
<head>
<title>An example HTMLDocument</title>
<style type="text/css">
div { background-color: silver; }
ul { color: red; }
</style>
</head>
<body>
<div id="BOX">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</div>
</body>
</html>

当我在浏览器中打开此 HTML 时,我只看到“第 1 段”和“第 2 段”(没有前导空格或换行符)。所以我认为“第 1 段”从偏移 0 开始。

但请考虑以下代码,我在示例 HTML 中打印文本和主体的偏移量:

import java.io.StringReader;
import javax.swing.text.Element;
import javax.swing.text.html.*;

public class Test {
public static void main(String[] args) throws Exception {
String html = " <html>\n"
+ " <head>\n"
+ " <title>An example HTMLDocument</title>\n"
+ " <style type=\"text/css\">\n"
+ " div { background-color: silver; }\n"
+ " ul { color: red; }\n"
+ " </style>\n"
+ " </head>\n"
+ " <body>\n"
+ " <div id=\"BOX\">\n"
+ " <p>Paragraph 1</p>\n"
+ " <p>Paragraph 2</p>\n"
+ " </div>\n"
+ " </body>\n"
+ " </html>\n";

HTMLEditorKit htmlKit = new HTMLEditorKit();
HTMLDocument doc = (HTMLDocument) htmlKit.createDefaultDocument();
htmlKit.read(new StringReader(html), doc, 0);

System.out.println("doc length: " + doc.getLength());
String text = doc.getText(0, doc.getLength());
System.out.println("doc text, surrounded by quotes, with newlines replaced with /: \""
+ text.replace('\n', '/') + "\"");

Element element = doc.getDefaultRootElement().getElement(1);
System.out.println("element name: " + element.getName());
int offset = element.getStartOffset();
System.out.println("offset of body: " + offset);
}
}

输出:

doc length: 26
doc text, surrounded by quotes, with newlines replaced with /: " /Paragraph 1/Paragraph 2"
element name: body
offset of body: 3

基本问题:为什么“Paragraph 1”(正文的开头)位于索引 3 处?文本的前三个字符(两个空格和一个换行符)来自哪里?我是否误解了“偏移量”的含义?

挑战问题:给定一些 HTML(简单到可以通过检查完全理解),我怎样才能严格地手工计算出所有 DOM 元素的偏移量?


更多信息:

如果我从 HTML 中删除 style 标签,我会得到相同的结果(3 的正文偏移量)。如果我还删除了 title,我得到的正文偏移量为​​ 1。如果我最终完全删除 head,我会得到 0 的正文偏移量(正如预期的那样)。那么显然 style 贡献了 0,title 贡献了 2,而 head 贡献了 1 到 body 的偏移量?这背后的原因是什么?

这似乎也不受 HTML 字符串中空格的影响。

最佳答案

好问题。您可以根据一些规则计算出偏移量(以及 JEditorPane 中必要的插入符位置)——您已经提到了最重要的规则。

也许有几个关键标签是:

  • <head> +1
  • <title> +2
  • <meta> +1
  • <p>文本长度 +1(对于 CR)

如果您还没有找到它,查看偏移量列表及其分解方式的最简单方法是 HTMLDocument.dump(System.out); .例如。对于上面的示例 HTML:

<html
name=html
>
<head
name=head
>
<p-implied
name=p-implied
>
<title
name=title
>
[0,1][ ]
<title
endtag=true
name=title
>
[1,2][ ]
<content
CR=true
name=content
>
[2,3][
]
<body
name=body
>
<div
id=BOX
name=div
>
<p
name=p
>
<content
name=content
>
[3,14][Paragraph 1]
<content
CR=true
name=content
>
[14,15][
]
<p
name=p
>
<content
name=content
>
[15,26][Paragraph 2]
<content
CR=true
name=content
>
[26,27][
]
<bidi root>
<bidi level
bidiLevel=0
>
[0,27][
Paragraph 1
Paragraph 2
]

如果您有兴趣深入研究,这将意味着探索 Swing 解析逻辑中的 HTML 规则。不同标签类型有很多规则 - 您可以在 source 中查看列表.

每个标签在此层次结构中使用一个“Action”类:

swing-html-actions

例如<p>ParagraphAction , 和 <head>HeadAction , 而这两个都是 BlockAction 的类型. <div>也是直接一个BlockAction .

A BlockAction可以添加额外的 <content CR...>元素,以完成 block ,因此偏移量额外+1。它通常只有在标签中有直接文本内容时才会这样做。对于 <head>不过,HeadAction子类添加了 <p-implied>您可以在上面的转储中看到,这导致了一个额外的偏移量。 (您在本例中看不到它,但值得注意的是带有文本内容的 <div> 还会插入额外的 <p-implied> - 以保存 block 文本)。

事情从那里开始变得更加具体。例如。 <title> (连同 <applet><object> )似乎是“非空” HiddenActions .这意味着为开始和结束标记都插入了一个元素。 <meta>虽然,例如,是一个空的 HiddenAction , 因此只获取一个元素作为开始标记。

希望这足以解释如何计算任何给定标签的偏移量。如果浏览 XxxActions 的源代码类,寻找类似 new ElementSpec(..., 0, 1) 的行- 最后一个参数是长度。

您还提到空格被忽略。这至少在 HTML 解析中是正常的,在浏览器中也是如此。标签之间或文本前后的空白通常会被忽略——只保留单词之间的空白。然后,空格序列被折叠成一个空格。


总而言之,我仍然不清楚为什么 <head> 需要额外的偏移量和 <title> .例如。如果你使用 setCaretPosition(x)针对 JEditorPane基于 dochtmlKit在上面,如果 x,您只会看到插入符号是3个或更多。也许其他人可以阐明这一点......

关于java - HTMLDocument 文本中位置或偏移量的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50602095/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com