Java HTMLDocument文本中位置或偏移的含义
我试图了解位置/偏移量在Java HTMLDocument文本中位置或偏移的含义,java,html,swing,Java,Html,Swing,我试图了解位置/偏移量在HTMLDocument中是如何工作的。描述了位置/偏移语义。我的解释是,这些是由HTMLDocument表示的屏幕字符序列中的索引 考虑以下HTML示例: HTMLDocument示例 div{背景色:银色;} ul{颜色:红色;} 第1款 第2款 当我在浏览器中打开这个HTML时,我只看到“段落1”和“段落2”(没有前导空格或换行符)。所以我认为“第1段”从偏移量0开始 但是请考虑下面的代码,在这里我打印示例HTML中的文本和正文的偏移: import java.
HTMLDocument
中是如何工作的。描述了位置/偏移语义。我的解释是,这些是由HTMLDocument
表示的屏幕字符序列中的索引
考虑以下HTML示例:
HTMLDocument示例
div{背景色:银色;}
ul{颜色:红色;}
第1款
第2款
当我在浏览器中打开这个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);
}
}
基本问题:为什么索引3
中有“第1段”(正文的开头)?文本的前三个字符(两个空格和一个换行符)来自哪里?我是否误解了“补偿”的含义
挑战性问题:给定一些HTML(足够简单,可以通过检查完全理解),我如何手动严格计算所有DOM元素的偏移量
更多信息: 如果我从HTML中删除
style
标记,我会得到相同的结果(主体偏移量3
)。如果同时删除标题
,则正文偏移量为1
。如果我最终完全移除头部
,我会得到0的躯干偏移量(如预期的那样)。显然,style
贡献了0,title
贡献了2,head
贡献了身体的偏移量1?这背后的原因是什么
这似乎也不受HTML字符串中空白的影响。好问题。您可以根据一些规则计算出偏移量(以及JEditorPane
中必要的插入符号位置)-您已经提到了最重要的规则
也许有几个关键标签是:
+1
+2
+1
文本长度+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
]
[0,1][ ]
[1,2][ ]
[2,3][
]
[3,14][第1段]
[14,15][
]
[15,26][第2段]
[26,27][
]
[0,27][
第1款
第2款
]
如果您有兴趣更深入地钻研,这将意味着探索HTML的Swing解析逻辑中的规则。对于不同的标记类型有很多规则-您可以在中看到列表
每个标记在此层次结构中使用一个“Action”类:
例如,
是一个段落动作
,
是一个头部动作
,这两种动作都是块动作
的类型。
也是直接的块操作
BlockAction
可以添加额外的
元素来完成块,因此偏移量上的额外+1。通常只有在标记中有直接文本内容时才会这样做。但是,对于
来说,HeadAction
子类添加了您可以在上面的转储中看到的
,这导致了一个额外的偏移。(在本例中您看不到它,但值得注意的是,带有文本内容的
也会插入额外的
-来保存块文本)
从那以后,事情变得越来越具体。例如,
(连同
和
)似乎是“非空的”HiddenActions
。这意味着将为开始标记和结束标记插入一个元素<代码>
但是,例如,它是一个空的HiddenAction
,所以只需要为start标记获取一个元素
希望这足以解释如何计算任何给定标记的偏移量。如果浏览XxxActions
类的源代码,请查找类似new ElementSpec(…,0,1)
的行-最后一个参数是长度
您还提到空白被忽略。这至少在HTML解析中是正常的,在浏览器中也是如此。标签之间或文本前后的空白通常被忽略-只保留单词之间的空白。然后,空格序列被压缩为一个空格
尽管如此,我仍然不清楚为什么
和
需要额外的偏移量。例如,如果根据上面的doc
和htmlKit
对JEditorPane
使用setCaretPosition(x)
,则只有当x
为3或更多时,您才会看到插入符号。也许其他人可以解释一下
<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
]