Значение положения или смещения в тексте HTMLDocument - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь понять, как работают позиции / смещения в HTMLDocument.Семантика положения / смещения описана здесь .Моя интерпретация заключается в том, что это индексы в последовательности экранных символов, представленных HTMLDocument.

Рассмотрим пример HTML из HTMLDocument документации :

 <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

Основные вопросы: Почему "Параграф 1" (начало тела) имеет индекс 3?Откуда появляются первые три символа (два пробела и новая строка) текста?Я неверно истолковываю, что означает «смещение»?

Задача: Учитывая некоторый HTML (достаточно простой, чтобы его можно было полностью понять при осмотре), как я могу точно определить смещения всех элементов DOM поhand?


Дополнительная информация:

Если я удалю тег style из HTML, я получу тот же результат (смещение тела 3).Если я также удалю title, я получу смещение тела 1.Если я окончательно удаляю head полностью, я получаю смещение тела 0 (как и ожидалось)Таким образом, очевидно, style добавляет 0, title добавляет 2, а head добавляет 1 к смещению тела?Какова причина этого?

Это также, кажется, не зависит от пробелов в строке HTML.

1 Ответ

0 голосов
/ 02 июня 2018

Хороший вопрос.Вы можете вычислить смещения (и, следовательно, необходимые позиции каретки в 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.A <div> также является BlockAction.

A BlockAction может добавить этот дополнительный элемент <content CR...>, чтобы завершить блок, следовательно, дополнительные +1 на смещении.Обычно это происходит, только если в теге было прямое текстовое содержимое.Для <head>, однако, подкласс HeadAction добавляет <p-implied>, который вы видите в дампе выше, что вызывает одно из дополнительных смещений.(Вы не можете видеть это в этом примере, но стоит отметить, что <div> с текстовым содержимым также добавляет дополнительные <p-implied> - для хранения текста блока).

С этого момента все более определенно становится более конкретным,Например, <title> (вместе с <applet> и <object>) кажутся "непустыми" HiddenActions.Это означает, что элемент вставляется для начального и конечного тегов.<meta> хотя, например, это пустой HiddenAction, поэтому просто получает один элемент для начального тега.

Надеюсь, этого достаточно для объяснения того, как вычислить смещение для любого данного тега.При просмотре исходного кода для классов XxxActions ищите строки, подобные new ElementSpec(..., 0, 1) - последний параметр - это длина.

Вы также упоминали, что пропуски игнорируются.По крайней мере, это нормально при разборе HTML, и в браузерах тоже.Пробелы между тегами или до и после текста обычно игнорируются - сохраняется только пробел между словами.И затем последовательности пробелов объединяются в один пробел.


При всем этом я до сих пор не понимаю, зачем нужны дополнительные смещения для <head> и <title>.Например, если вы используете setCaretPosition(x) против JEditorPane на основе doc и htmlKit выше, вы увидите только, если x равно 3 или больше.Возможно, кто-то еще может пролить свет на это ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...