Jsoup — Как очистить html, экранируя, не удаляя ненужный html?

#jsoup

#jsoup

Вопрос:

Есть ли способ заставить jsoup очистить строку с HTML в ней, экранируя нежелательный HTML, а не удаляя его полностью? Мой пример:

 String dirty = "This is <b>REALLY</b> dirty code from <a href="www.rubbish.url.zzzz">haxors-r-us</a>
String clean = Jsoup.clean(dirty, new Whitelist().addTags("a").addAttributes("a", "href", "name", "rel", "target"));
  

Это дает «чистую» строку:

 This is    REALLY    dirty code from <a href="www.rubbish.url.zzzz">haxors-r-us</a>
  

Я хочу, чтобы «чистая» строка была:

 "This is amp;<bamp;>REALLYamp;</bamp;> dirty code from <a href="www.rubbish.url.zzzz">haxors-r-us</a>
  

Комментарии:

1. Хороший. Нет, Jsoup его не поддерживает. Возможно, вы захотите опубликовать запрос функции на github.com/jhy/jsoup/issues чтобы добавить новый метод в Whitelist API, который может превратить удаление HTML в экранирование HTML.

2. Опубликованный запрос функции: github.com/jhy/jsoup/issues/515

Ответ №1:

Предполагая, что анализируются строковые, а не HTML-документы (согласно вашему вопросу), этот метод будет работать:

 public String escapeHtml(String source) {
    Document doc = Jsoup.parseBodyFragment(source);
    Elements elements = doc.select("b");
    for (Element element : elements) {
        element.replaceWith(new TextNode(element.toString(),""));
    }
    return Jsoup.clean(doc.body().toString(), new Whitelist().addTags("a").addAttributes("a", "href", "name", "rel", "target"));
}
  

Вы можете сделать тег «b» аргументом для передачи списка тегов, которые вы хотите экранировать.

Связанный с прохождением JUnit-теста:

 @Test
public void testHtmlEscaping() throws Exception {
    String source = "This is <b>REALLY</b> dirty code from <a href="www.rubbish.url.zzzz">haxors-r-us</a>";
    String expected = "This is amp;<bamp;>REALLYamp;</bamp;> dirty code from n<a href="www.rubbish.url.zzzz">haxors-r-us</a>";
    String transformed = transformer.escapeHtml(source);
    assertEquals(transformed, expected);
}
  

Обратите внимание, что я добавил строку возврата » n» перед вашим тегом «a» в «ожидаемой» строке моего теста, потому что JSoup форматирует страницу.