Как показать сравнение 2 текстовых блоков HTML - PullRequest
8 голосов
/ 01 сентября 2009

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

Я использовал класс PEAR Text_Diff для успешной визуализации сравнений простого текста, но когда я пытаюсь выбросить текст с тегами html, он становится УЖАСНЫМ. Из-за алгоритмов сравнения на основе слов и символов, используемых классом, теги html ломаются, и я получаю уродливые вещи вроде <p><span class="new"> </</span>p>. Это убивает HTML.

Есть ли способ сгенерировать сравнение текста при сохранении исходной действительной разметки HTML?

Спасибо за помощь. Я работал над этим неделями: [

Это лучшее решение, которое я мог придумать: найти / заменить каждый тип тега html на 1 специальный нестандартный символ, такой как логотип apple (opt shift k), отрендерить сравнение с этим типом первичной уценки, а затем отменить нестандартные символы возвращаются в теги. Есть отзывы?

Ответы [ 6 ]

3 голосов
/ 01 сентября 2009

Simple Diff Пола Батлера выглядит так, будто он предназначен именно для того, что вам нужно: http://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php

Обратите внимание, что в его php-коде есть HTML-оболочка: htmlDiff ($ old, $ new)

(Его пост в блоге: http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

1 голос
/ 07 января 2014

Интересно, что никто не упомянул HTMLDiff на основе Visual Diff MediaWiki. Попробуйте, я искал что-то вроде вас и нашел это довольно полезным.

1 голос
/ 01 сентября 2009

Как насчет использования HTML Tidier / Formatter в каждом блоке в первую очередь? Это создаст стандартную «структуру», которую ваш diff мог бы найти легче проглотить

1 голос
/ 01 сентября 2009

Кажется, проблема в том, что ваша программа сравнения должна обрабатывать существующие теги HTML как атомарные токены, а не как отдельные символы.

Если ваш движок имеет возможность ограничивать себя работой с границами слов, посмотрите, можете ли вы переопределить функцию, которая определяет границы слов, чтобы он распознавал и обрабатывал теги HTML как одно «слово».

Вы также можете сделать, как вы говорите, и создать словарь поиска различных HTML-тегов, который заменяет каждый из них уникальным неиспользуемым значением Unicode (я думаю, что вы можете использовать некоторые пользовательские диапазоны). Однако, если вы сделаете это, любые изменения в разметке будут обрабатываться так, как если бы они были изменением предыдущего или следующего слова, потому что символ Unicode станет частью этого слова для токенизатора. Добавление пробела до и после каждого из ваших символов токена Unicode позволит сохранить изменения HTML-тега отдельно от изменений простого текста.

0 голосов
/ 20 октября 2009

Копия моего собственного ответа от здесь .


Как насчет DaisyDiff ( Java и PHP доступны версии).

Следующие функции действительно хороши:

  • Работает с плохо сформированным HTML, который можно найти «в дикой природе».
  • Различия в HTML более специализированы, чем в дереве XML. Изменение части текстового узла не приведет к изменению всего узла.
  • В дополнение к визуальному различию по умолчанию, источник HTML может быть связан когерентно.
  • Предоставляет понятные описания изменений.
  • Стандартный графический интерфейс пользователя позволяет легко просматривать изменения с помощью сочетаний клавиш и ссылок.
0 голосов
/ 01 сентября 2009

Попробуйте сначала запустить блоки HTML через эту функцию:

htmlentities();

Это должно преобразовать все ваши "<" и ">" в соответствующие им коды, что, возможно, решит вашу проблему.

//Example:
$html_1 = "<html><head></head><body>Something</body></html>"
$html_2 = "<html><head></head><body><p id='abc'>Something Else</p></body></html>"

//Below code taken from http://www.go4expert.com/forums/showthread.php?t=4189.
//Not sure if/how it works exactly

$diff = &new Text_Diff(htmlentities($html_1), htmlentities($html_2));
$renderer = &new Text_Diff_Renderer();
echo $renderer->render($diff);
...