关于如何构建HTML Diff工具的建议?

在这篇文章中,我询问是否有任何工具可以比较2个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元素放入树中,然后比较两棵树。 如果标签名称不同,则节点不同。 您可能想要在某一点停止枚举(您可能不关心span,粗体,斜体等等 – 可能只关心div?),因为有些标签实际上是内容,而不是结构,页。

如果我要解决这个问题,我会这样做:

  1. 为html页面规划某种DOM。 从轻量级开始,然后根据需要添加更多。 我会使用复合模式作为数据结构。 即每个元素都有基类类型的子集合。
  2. 创建解析器来解析html页面。
  3. 使用解析器将html元素加载到DOM。
  4. 页面加载到DOM后,您将获得html页面结构的层次快照。
  5. 继续遍历两侧的每个元素,直到DOM结束。 当你遇到不匹配的元素类型时,你会在结构中找到差异。

在您的示例中,您将只在一侧加载div元素对象,在另一侧,您将有一个div元素对象加载1个子元素类型为paragraph元素。 启动你的迭代器,首先你将匹配div元素,第二个迭代器你将匹配段落什么都没有。 你有结构上的差异。

我认为上面的一些建议没有考虑到两个页面之间的HTML中存在其他文本不同的标记,但生成的HTML标记在function上是等效的。 Danimal列出控件ID作为示例。

以下两个标记function完全相同,但如果您只是比较标记,则会显示为不同:

 
foo
foo

我打算建议Danimal编写HTML翻译,查找HTML标签,并将两个文档转换为两者的简化版本,省略ID标签和您指定为无关的任何其他标签。 这可能必须是一项正在进行的工作,因为您忽略了某些属性/标签,然后遇到了您也想忽略的新属性/标签。

但是,我喜欢使用XmlSchemaInterface将其简化为XML模式,然后使用了解XML规则的diff工具。

有关由langauge语法参数化的工具,请参阅http://www.semdesigns.com/Products/SmartDifferencer/index.html ,并根据语言元素(标识符,表达式,语句,块,方法等)生成增量。插入,删除,移动,替换或标识符一致地替换它。 此工具忽略空格重新格式化(例如,不同的换行符或布局)和语义上无法区分的值(例如,它知道0x0F和15是相同的值)。 这可以使用HTML解析器应用于HTML。

编辑:9/12/2009。 我们使用HTML编辑器构建了一个实验性的SmartDiff工具。

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

适用于FF 3.5。 我还没有测试过FF 3.6。

请参阅此前的post和随附的答案 。

这是一个很好的开始。 还有一些澄清/评论:

  • 我可能不关心ID,因为.net会破坏它们
  • 一些结构将在转发器或其他此类控件中,因此我可能最终会有更多或更少的重复元素

进一步思考:我认为一个好的开始是假设html符合XHTML。 然后,我可以推断出模式(使用新的.net XmlSchemaInference方法),然后区分模式。 然后,我可以看看差异,并考虑它们是否重要。

我的建议只是这样做的基本方法……当然要解决你提到的问题,你必须在这里应用其他规则……在你的情况下,我们得到一个匹配的div元素,然后应用属性/属性匹配规则,什么不……

说实话,有许多复杂的规则需要应用于比较,而不仅仅是与另一个元素的简单匹配元素。 例如,如果您有重复项会发生什么。 例如,一侧为1 div元素,另一侧为2 div元素。 你将如何匹配哪些div元素匹配在一起?

你会在比较词中找到很多其他复杂的问题。 我根据经验说话(我的工作的一部分是保持我的公司文本比较引擎)。

看看超越比较。 它具有XML比较function,可以帮助您。

您可能还必须考虑“内容”本身可能包含额外的标记,因此在进行比较之前,可能需要删除某些元素中的所有内容(例如具有特定ID或类的

)。 例如:

 

lorem ipsum etc..

 

Here is some real content

  • and
  • some
  • more..

Pretty Diff可以做到这一点。 它将仅比较代码结构,无论与空格,注释甚至内容的差异如何。 请务必选中“规范内容和字符串文字”选项。

http://prettydiff.com/

我会使用(或贡献) html5lib及其SAX输出。 只需压缩2个SAX流即可查找不匹配项,并突出显示整个相应的子树。

我不知道任何工具,但我知道有一个简单的方法可以做到这一点:

  • 首先,使用正则表达式工具去除HTML文件中的所有文本。 您可以使用此正则表达式搜索文本( ?<=^|>)[^><]+?(?=<|$ )并将其替换为空字符串( "" ),即删除所有文本。 完成此步骤后,您将拥有所有HTML标记标记。 那里有很多免费的正则表达式工具。
  • 然后,重复原始HTML文件的第一步。
  • 最后,使用diff工具比较两组HTML标记。 这将显示一组与另一组之间缺少的内容。

如果我这样做,首先我会学习HTML。 (^ – ^)然后,我将构建一个工具,剥离所有实际内容,然后将其保存为文件,以便它可以通过WinDiff(或其他合并工具)进行管道传输。

在浏览器中打开每个页面并将其另存为.htm文件。 比较两个使用windiff。