Вставьте HTML в тело HTMLDocument - PullRequest
       37

Вставьте HTML в тело HTMLDocument

6 голосов
/ 12 августа 2010

Кажется, это такой простой вопрос, но у меня такие трудности.

Проблема:

У меня есть текст для вставки в HTMLDocument. Этот текст иногда также определяет некоторые HTML. E.G.:

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

Я использую HTMLEditorKit.insertHTML, чтобы вставить его с указанным смещением. Это работает нормально, если только смещение не находится в начале документа (offset = 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 Я был бы открыт для этих идей а также.

Любая помощь будет принята с благодарностью. Спасибо!

1 Ответ

6 голосов
/ 19 августа 2010

Есть несколько вещей, которые вы должны знать о внутренней структуре HTMLDocument.

  • Прежде всего - тело не начинается с позиции 0. Все текстовое содержимое документа хранится в экземпляре javax.swing.text.AbstractDocument$Content. Это включает в себя теги title и script. Аргумент позиции / смещения ЛЮБОГО документа и функции редактора ссылается на текст в этом экземпляре Content! Вы должны определить начало элемента body, чтобы правильно вставить содержимое в тело. Кстати: даже если вы не определили элемент body в своем HTML, он будет автоматически сгенерирован синтаксическим анализатором.
  • Простая вставка в позиции, как правило, имеет неожиданные побочные эффекты. Вам нужно знать, куда вы хотите поместить контент по отношению к элементам (HTML) в этой позиции. Например. если в вашем документе есть следующий текст: «...</span><span>...» - есть только одна позиция (ссылаясь на экземпляр Content) для «в конце первого промежутка», «между промежутками» и «в начале второй пролёт ". Для решения этой проблемы в API HTMLDocument есть 4 функции:
    • insertAfterEnd
    • insertAfterStart
    • insertBeforeEnd
    • insertBeforeStart

В заключение: для общих решений вы должны найти элемент 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 всегда работает.

...