Сопоставление вывода PegDown+JSoup с выводом PageDown

Я пытаюсь разобрать и очистить уценку на стороне клиента и сервера.

  • На стороне клиента я использую PageDown в качестве редактора уценки. Это именно то, что использует StackOverflow, и он поставляется с отличным окном предварительного просмотра. В этом окне предварительного просмотра отображается очищенный HTML-код, поэтому он удаляет такие элементы, как теги <div>.

  • На стороне сервера я использую PegDown и JSoup для анализа и очистки уценки.

Тем не менее, я нахожу случаи, когда вывод двух не совпадает. Например:

Введите уценку: how are <div>tags</div> treated?

Вывод PageDown: <p>how are tags treated?</p>

Вывод PegDown/JSoup:

<p>how are </p>tags treated?
<p></p>

Я не делаю ничего особенного с JSoup. Вот мой код:

public class Main {

    public static void main(String... args){

        PegDownProcessor pdp = new PegDownProcessor();

        String markdown = "how are <div>tags</div> treated?";

        String html = pdp.markdownToHtml(markdown);

        Whitelist whitelist = Whitelist.relaxed().removeTags("div");

        html = Jsoup.clean(html, whitelist);
        System.out.println(html);

        System.out.println("Done.");
    }
}

Я понимаю, почему это происходит, и меня не удивляет, что две разные системы генерируют два разных результата. Мой вопрос: как настроить JSoup, чтобы он просто удалял теги <div> вместо добавления дополнительных тегов <p>?

Моя конечная цель состоит в том, чтобы просто синтаксический анализ/санация на стороне сервера генерировать достаточно похожие результаты на синтаксический анализ/санитарную обработку на стороне клиента. Если есть лучшие способы сделать это, я открыт для предложений. Мне все равно, будут ли выходные данные двух одинаковыми, но такие вещи, как дополнительные теги <p>, будут очень заметны для пользователей, поэтому я пытаюсь устранить это одно существенное различие.

Дополнительный вопрос: есть ли список HTML-тегов и атрибутов, которые может выводить PageDown?

Изменить: я также пытался использовать дезинфицирующее средство OWASP, но я получаю очень похожие результаты: теги <div> удаляются, но теги <p> "исправлены" вышеописанным способом, что приводит к другому html, чем дезинфицирующее средство PageDown.


person Kevin Workman    schedule 18.03.2016    source источник


Ответы (1)


как настроить JSoup так, чтобы он просто удалял теги ‹div> вместо добавления дополнительных тегов ‹p>?

Спецификации HTML 5 запрещают использование элемента div внутри элемента p. Jsoup учитывает эти спецификации, поэтому в итоговой строке html есть два элемента p.

Чтобы лучше понять, почему это происходит, давайте посмотрим, как работает Jsoup#clean, в три шага:

  1. Разобрать грязный HTML
  2. Настройте полученное дерево, чтобы оно соответствовало спецификациям HTML 5.
  3. Удалить запрещенные теги

На шаге 2 первый тег <p> закрывается непосредственно перед открывающим div. Второй p тоже получает свой открывающий тег на этом же шаге. Поскольку Jsoup не знает, где начинается допустимое содержание этого абзаца, он ограничивает содержание этого второго абзаца строгой суммой (т.е. ничем).

Действия на шагах 1 и 2 создают новый HTML-код, соответствующий спецификациям HTML 5. На шаге 3 теперь можно удалить div.

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

Чтобы избежать других случаев, подобных описанному здесь, вы должны использовать одну и ту же систему как на стороне клиента, так и на стороне сервера. Поскольку Pagedown написан на Javascript, вы можете попробовать запустить его внутри движка Javascript на стороне сервера.

Назвать несколько:

  • Насхорн (встроен в Java 8)
  • носорог
  • V8

ОБРАЗЕЦ КОДА

Вот пример, иллюстрирующий использование Nashorn:

Caller.java

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));

Invocable invocable = (Invocable) engine;

Object result = invocable.invokeFunction("myFunction", "fooValue");

System.out.println(result);
System.out.println(result.getClass());

script.js

function myFunction(foo) {
   // ...
}

СМОТРИТЕ ТАКЖЕ

person Stephan    schedule 21.03.2016
comment
Это не работает для меня. Вывод должен быть <p>how are tags treated?</p>, но если я оберну уценку в теги <body>, вывод будет просто how are tags treated? без каких-либо тегов html. Это будет еще хуже для реальных данных, которые намного длиннее одной строки. - person Kevin Workman; 21.03.2016
comment
@KevinWorkman Я думаю, что вы снова и снова будете сталкиваться с крайними случаями, когда выходные данные двух систем расходятся. Подробности смотрите в моем обновлении... - person Stephan; 21.03.2016
comment
Да, я понимаю, почему он закрывает тег <p>. Я ищу способ отключить эту функцию или, по крайней мере, изменить этапы очистки, чтобы <div> удалялось до того, как дерево станет действительным. Забавно, но серверный подход JavaScript — это именно то, что я попробовал первым. Это не работает из-за известной ошибки. - person Kevin Workman; 21.03.2016
comment
Только что заработал V8. Кажется, это помогает. Теперь мне просто нужно выяснить, какие нативы мне нужны на моем сервере. +1 на данный момент, и если больше никто не придет, я отмечу как правильный и награжу вас наградой. - person Kevin Workman; 21.03.2016