Использование jsoup для обхода запрещенных тегов

Я оцениваю jsoup на предмет функциональности, которая будет очищать (но не удалять!) теги, не внесенные в белый список. Допустим, разрешен только тег <b>, поэтому следующий ввод

foo <b>bar</b> <script onLoad='stealYourCookies();'>baz</script>

должно получиться следующее:

foo <b>bar</b> &lt;script onLoad='stealYourCookies();'&gt;baz&lt;/script&gt;

Я вижу следующие проблемы/вопросы с jsoup:

  • document.getAllElements() всегда предполагает <html>, <head> и <body>. Да, я могу вызвать document.body().getAllElements(), но дело в том, что я не знаю, является ли мой источник полным HTML-документом или просто телом, и я хочу, чтобы результат имел ту же форму и вид, в каком он был получен;
  • как заменить <script>...</script> на &lt;script&gt;...&lt;/script&gt;? Я хочу только заменить скобки экранированными объектами и не хочу изменять какие-либо атрибуты и т. д. Node.replaceWith звучит как излишество для этого.
  • Можно ли полностью отключить красивую печать (например, вставку новых строк и т. д.)?

Или, может быть, я должен использовать другой фреймворк? До сих пор я заглядывал в htmlcleaner, но приведенные примеры не предполагают, что мои желаемые функции поддерживаются.


person mindas    schedule 20.02.2012    source источник


Ответы (1)


Ответ 1

Как вы загружаете / анализируете свой Document с помощью Jsoup? Если вы используете parse() или connect().get(), jsoup автоматически отформатирует ваш html (вставив теги html, body и head). Это гарантирует, что у вас всегда будет полный HTML-документ, даже если ввод не завершен.

Предположим, вы хотите только очистить ввод (без дальнейшей обработки), вы должны использовать clean() вместо предыдущих перечисленных методов.

Пример 1. Использование parse()

final String html = "<b>a</b>";

System.out.println(Jsoup.parse(html));

Вывод:

<html>
 <head></head>
 <body>
  <b>a</b>
 </body>
</html>

Входной HTML-код завершен, чтобы убедиться, что у вас есть полный документ.

Пример 2. Использование функции clean()

final String html = "<b>a</b>";

System.out.println(Jsoup.clean("<b>a</b>", Whitelist.relaxed()));

Вывод:

<b>a</b>

Входной html чистится, не более.

Документация:


Ответ 2

Метод replaceWith() делает именно то, что вам нужно:

Пример:

final String html = "<b><script>your script here</script></b>";
Document doc = Jsoup.parse(html);

for( Element element : doc.select("script") )
{
    element.replaceWith(TextNode.createFromEncoded(element.toString(), null));
}

System.out.println(doc);

Вывод:

<html>
 <head></head>
 <body>
  <b>&lt;script&gt;your script here&lt;/script&gt;</b>
 </body>
</html>

Или только тело:

System.out.println(doc.body().html());

Вывод:

<b>&lt;script&gt;your script here&lt;/script&gt;</b>

Документация:


Ответ 3

Да, prettyPrint() метод Jsoup.OutputSettings делает это.

Пример:

final String html = "<p>your html here</p>";

Document doc = Jsoup.parse(html);
doc.outputSettings().prettyPrint(false);

System.out.println(doc);

Примечание. если метод outputSettings() недоступен, обновите Jsoup.

Вывод:

<html><head></head><body><p>your html here</p></body></html>

Документация:


Ответ 4 (без маркера)

Нет! Jsoup — одна из лучших и наиболее функциональных HTML-библиотек!

person ollo    schedule 09.02.2013
comment
Вау, спасибо за очень подробный ответ! Я немного не в контексте этой проблемы в данный момент, но посмотрю на это позже. - person mindas; 09.02.2013