Предложения о том, как создать инструмент HTML Diff?

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

Нить предложила несколько хороших предложений, но ничего не соответствовало законопроекту. «Прекрасно, тогда», подумал я, «я просто провожу кого-то из себя. Я прилежный разработчик, верно?».

Ну, когда я начал думать об этом, я не мог понять, как это сделать. Я могу легко прокрутить управляемый данными веб-сайт или выполнить CMS или бросить документы в BizTalk и весь день. Невозможно понять, как сравнивать документы HTML.

Ну, конечно, я должен прочитать DOM и перебрать узлы. Мне нужно сопоставить структуру с некоторой структурой данных (как?), А затем сравнить их (как?). Это задача разработки, как никто из моих попыток.

Итак, теперь, когда я обнаружил слабость в своих знаниях, мне еще более сложно понять это. Любые предложения о том, как начать работу?

разъяснение: фактическое содержание не то, что я хочу сравнить – творческие парни заполняют свои страницы lorem ipsum , и я использую настоящий контент. Вместо этого я хочу сравнить структуру:

 
lorem ipsum

отличается от



lorem ipsum


DOM – структура данных – это дерево.

Запустите оба файла с помощью следующего скрипта Perl, а затем используйте diff -iw, чтобы сделать регистр без учета регистра, пробельный-игнорирующий diff.

#! /usr/bin/perl -w use strict; undef $/; my $html = ; while ($html =~ /\S/) { if ($html =~ s/^\s*// or die "malformed HTML"; print "< $1>\n"; } else { $html =~ s/^([^< ]+)//; print "(text)\n"; } } 

@Mike – это будет сравнивать все, в том числе содержимое страницы, которое не хочет, чтобы оригинальный плакат хотел.

Предполагая, что у вас есть доступ к DOM браузера (написав плагин Firefox / IE или что-то еще), я бы, вероятно, поместил все элементы HTML в дерево, а затем сравнил два дерева. Если имя тега отличается, то узел отличается. Возможно, вам захочется прекратить перечисление в определенный момент (возможно, вам небезразличен диапазон, полужирный, курсив и т. Д. – может быть, только беспокоиться о divs?), Поскольку некоторые tags – это действительно контент, а не структура, стр.

Если бы я должен был решить эту проблему, я бы сделал следующее:

  1. Планируйте какой-то DOM для html-страниц. начинается с легкого веса, а затем добавляет больше по мере необходимости. Я бы использовал составную структуру для структуры данных. т.е. каждый элемент имеет дочернюю совокупность типа базового classа.
  2. Создайте парсер для parsingа html-страниц.
  3. Использование элемента hsml загрузки парсера в DOM.
  4. После того, как страницы были загружены в DOM, у вас есть иерархический снимок структуры html-страниц.
  5. Продолжайте повторять все элементы с обеих сторон до конца DOM. Вы обнаружите diff в структуре, когда вы нажмете несоответствие типа элемента.

В вашем примере у вас будет только объект элемента div, загруженный с одной стороны, с другой стороны у вас будет объект элемента div, загруженный 1 дочерним элементом элемента абзаца типа. запустите свой iterator, сначала вы сравните элемент div, второй iterator, который вы соедините с абзацем ни с чем. У вас есть свое структурное различие.

Я думаю, что некоторые из приведенных выше предложений не учитывают, что в HTML есть другие tags между двумя страницами, которые были бы текстовыми, но полученная разметка HTML функционально эквивалентна. В качестве примера приводятся контрольные идентификаторы Danimal.

Следующие две разметки функционально идентичны, но будут отображаться как разные, если вы просто сравнили tags:

 
foo
foo

Я собирался предложить Danimal написать HTML-перевод, который ищет HTML-tags и преобразует оба документа в упрощенную версию обоих, которые опускают tags идентификаторов и любые другие tags, которые вы обозначаете как несущественные. Вероятно, это должна быть работа, поскольку вы игнорируете определенные атрибуты / tags, а затем запускаете новые, которые вы также хотите игнорировать.

Однако мне нравится идея использования XmlSchemaInterface, чтобы свернуть ее до схемы XML, а затем использовать инструмент diff, который понимает правила XML.

См. http://www.semdesigns.com/Products/SmartDifferencer/index.html для инструмента, который параметризуется грамматикой langauge, и производит дельта в терминах элементов языка (идентификаторы, выражения, утверждения, блоки, методы, … ) вставлены, удалены, перемещены, заменены или имеют одинаковые идентификаторы. Этот инструмент игнорирует переформатирование в виде пробелов (например, различные разрывы строк или макеты) и семантически неразличимые значения (например, он знает, что 0x0F и 15 являются одинаковым значением). Это можно применить к HTML с помощью парсера HTML.

EDIT: 9/12/2009. Мы создали экспериментальный инструмент SmartDiff, используя редактор HTML.

http://www.mugo.ca/Products/Dom-Diff

Работает с FF 3.5. Я еще не тестировал FF 3.6.

См. Предыдущий пост и сопроводительные ответы .

Это было отличное начало. Еще несколько пояснений / комментариев:

  • Мне, вероятно, не нужны идентификаторы, так как .net будет их калечить
  • часть структуры будет находиться в повторителе или другом таком контроле, так что я могу в итоге получить больше или меньше повторяющихся элементов

дальнейшая мысль: я думаю, что хорошим началом было бы предположить, что html соответствует XHTML. Затем я мог бы вывести схему (используя новые методы .net XmlSchemaInference), а затем разобрать схемы. Затем я могу разобраться в различиях и подумать, важны они или нет.

Мое предложение – это всего лишь основной способ сделать это … Конечно, чтобы решить проблему, о которой вы говорили, здесь должны быть применены дополнительные правила … Что в вашем случае, мы получили соответствующий элемент div, а затем применяем атрибуты / соответствие свойств правила, а что нет …

Честно говоря, существует множество и сложных правил, которые необходимо применять для сравнения, а также не просто простой элемент соответствия для другого элемента. Например, что произойдет, если у вас есть дубликаты. например, один элемент div на одной стороне и 2 div-элемент на другой стороне. Как вы собираетесь совместить элементы div с совпадением?

Есть и другие сложные проблемы, которые вы найдете в слове сравнения. Я говорю на основе опыта (часть моей работы заключается в том, чтобы maitain механизм сравнения текста моей компании).

Взгляните дальше, чем сравнивать. Он имеет функцию сравнения XML, которая может помочь вам.

Возможно, вам также придется подумать, что сам контент может содержать дополнительную надбавку, поэтому, прежде чем вы сделаете сравнение, вероятно стоит убрать все внутри определенных элементов (например,

s с определенными идентификаторами или classами). Например:

 

lorem ipsum etc..

а также

 

Here is some real content

  • and
  • some
  • more..

Pretty Diff может это сделать. Он будет сравнивать структуру кода только независимо от различий с пробелами, комментариями или даже содержанием. Просто не забудьте проверить параметр «Нормализовать содержимое и литералы струн».

http://prettydiff.com/

Я бы использовал (или вносил вклад) в html5lib и его SAX-выход. Просто запустите zip через 2 streamа SAX, ищите несоответствия и выделите все соответствующее поддерево.

Я не знаю никакого инструмента, но я знаю, что есть простой способ сделать это:

  • Во-первых, используйте инструмент регулярного выражения, чтобы удалить весь текст в вашем HTML-файле. Вы можете использовать это регулярное выражение для поиска текста ( ?< =^|>)[^>< ]+?(?=<|$ ) И заменить их пустой строкой ( "" ), то есть удалить весь текст , После этого шага вы будете иметь все tags разметки HTML. Там есть много бесплатных инструментов регулярного выражения.
  • Затем вы повторяете первый шаг для исходного HTML-файла.
  • Наконец, вы используете инструмент diff для сравнения двух наборов разметки HTML. Это покажет, что отсутствует между одним набором и другим.

Если бы я это сделал, сначала я бы изучил HTML. (^ – ^) Тогда я бы построил инструмент, который удаляет все фактическое содержимое, а затем сохраняет это как файл, чтобы он мог быть передан через WinDiff (или другой инструмент слияния).

Откройте каждую страницу в браузере и сохраните их как .htm-файлы. Сравните два, используя windiff.