Предложения о том, как создать инструмент HTML Diff? - PullRequest
11 голосов
/ 17 сентября 2008

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

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

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

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

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

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

<div class="foo">lorem ipsum<div>

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

<br/><div class="foo"><br/><p>lorem ipsum<p><br/><div>

Ответы [ 17 ]

2 голосов
/ 18 сентября 2008

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

#! /usr/bin/perl -w

use strict;

undef $/;

my $html = <STDIN>;

while ($html =~ /\S/) {
  if ($html =~ s/^\s*<//) {
    $html =~ s/^(.*?)>// or die "malformed HTML";
    print "<$1>\n";
  } else {
    $html =~ s/^([^<]+)//;
    print "(text)\n";
  }
}
2 голосов
/ 17 сентября 2008

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

1 голос
/ 17 июня 2009

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

РЕДАКТИРОВАТЬ: 12.12.2009. Мы создали экспериментальный инструмент SmartDiff с использованием редактора HTML.

1 голос
/ 17 сентября 2008

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

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

1 голос
/ 18 сентября 2008

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

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

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

1 голос
/ 27 июля 2010

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

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

1 голос
/ 18 сентября 2008

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

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

<div id="ctl00_TopNavHome_DivHeader" class="header4">foo</div>
<div class="header4">foo</div>

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

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

0 голосов
/ 28 марта 2010

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

0 голосов
/ 12 сентября 2009

Возможно, вам также придется учесть, что сам «контент» может содержать дополнительную разметку, поэтому, вероятно, стоит вычеркнуть все в определенных элементах (например, <div> s с определенными идентификаторами или классами), прежде чем проводить сравнение. Например:

<div id="mainContent">
<p>lorem ipsum etc..</p>
</div>

и

<div id="mainContent">
<p>Here is some real content<img class="someImage" src="someImage.jpg" /></p>
<ul>
<li>and</li>
<li>some</li>
<li>more..</li>
</ul>
</div>
0 голосов
/ 12 сентября 2009

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

...