在this post中我询问是否有任何工具可以比较2个HTML页面的结构(而非实际内容)。我问,因为我从设计师那里收到HTML模板,并经常错过我的实现中的次要格式更改。然后我浪费了几个小时的设计师时间筛选我的页面来发现我的错误。
该主题提供了一些很好的建议,但没有任何东西适合该法案。 “好吧,然后”,我想,“我只是自己动摇一下。我是一个不太合适的开发者,对吧?”。
好吧,一旦我开始思考它,我就无法弄清楚如何去做。我可以轻松地创建一个数据驱动的网站,或者进行CMS实施,或者整天将文档放入和放出BizTalk。无法开始弄清楚如何比较HTML文档。
嗯,当然,我必须阅读DOM,并遍历节点。我必须将结构映射到一些数据结构(如何??),然后比较它们(如何??)。这是一项我从未尝试过的开发任务。
所以现在我已经发现了我的知识中的一个弱点,我更难以弄明白这一点。关于如何开始的任何建议?
澄清:实际的内容不是我想要比较的 - 创意人用 lorem ipsum 填充他们的页面,我使用真实的内容。相反,我想比较结构:
<div class="foo">lorem ipsum<div>
不同
<div class="foo">
<p>lorem ipsum<p>
<div>
答案 0 :(得分:2)
DOM是一种数据结构 - 它是一棵树。
答案 1 :(得分:2)
通过以下Perl脚本运行这两个文件,然后使用diff -iw执行不区分大小写,忽略空格的差异。
#! /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 :(得分:1)
@Mike - 可以比较所有内容,包括页面内容,这不是原版海报所需要的。
假设您可以访问浏览器的DOM(通过编写Firefox / IE插件或其他内容),我可能会将所有HTML元素放入树中,然后比较两棵树。如果标记名称不同,则节点不同。你可能想要在某一点停止枚举(你可能不关心span,粗体,斜体等等 - 也许只关心div?),因为有些标签实际上是内容,而不是结构,页。
答案 3 :(得分:1)
http://www.mugo.ca/Products/Dom-Diff
适用于FF 3.5。我还没有测试过FF 3.6。
答案 4 :(得分:1)
有关由langauge语法参数化的工具,请参阅http://www.semdesigns.com/Products/SmartDifferencer/index.html,并根据插入,删除,移动,替换的语言元素(标识符,表达式,语句,块,方法等)生成增量,或者标识符一致地替换它。该工具忽略空白重新格式化(例如,不同的换行符或布局)和语义上不可区分的值(例如,它知道0x0F和15是相同的值)。 这可以使用HTML解析器应用于HTML。
编辑:9/12/2009。我们使用HTML编辑器构建了一个实验性SmartDiff工具。
答案 5 :(得分:1)
我认为上面的一些建议没有考虑到两个页面之间的HTML中存在其他文本不同的标记,但生成的HTML标记在功能上是等效的。 Danimal列出控件ID作为示例。
以下两个标记功能完全相同,但如果您只是比较标记,它们会显示为不同:
<div id="ctl00_TopNavHome_DivHeader" class="header4">foo</div>
<div class="header4">foo</div>
我打算建议Danimal编写HTML翻译,查找HTML标签并将两个文档转换为两者的简化版本,这些版本会省略ID标签和您指定为无关的任何其他标签。这可能必须是一项正在进行的工作,因为您忽略了某些属性/标签,然后遇到了您也想忽略的新属性/标签。
但是,我喜欢使用XmlSchemaInterface将其简化为XML模式,然后使用了解XML规则的diff工具。
答案 6 :(得分:1)
如果我要解决这个问题,我会这样做:
在您的示例中,您将只在一侧加载div元素对象,在另一侧,您将有一个div元素对象加载1个子元素类型为paragraph元素。启动你的迭代器,首先你将匹配div元素,第二个迭代器你将匹配段落什么都没有。你有结构上的差异。
答案 7 :(得分:0)
这是一个很好的开始。还有一些澄清/评论:
进一步思考: 我认为一个好的开始是假设html符合XHTML。然后我可以推断出架构(使用新的.net XmlSchemaInference方法),然后对架构进行区分。然后,我可以看看差异,并考虑它们是否重要。
答案 8 :(得分:0)
我不知道任何工具,但我知道有一种简单的方法可以做到这一点:
?<=^|>)[^><]+?(?=<|$
)并将其替换为空字符串(""
),即删除所有文本。完成此步骤后,您将拥有所有HTML标记标记。那里有很多免费的正则表达式工具。答案 9 :(得分:0)
我的建议只是这样做的基本方法......当然要解决你提到的问题,你必须在这里应用其他规则......在你的情况下,我们得到一个匹配的div元素,然后应用属性/属性匹配规则和什么不...
说实话,有许多复杂的规则需要应用于比较,而不仅仅是与另一个元素的简单匹配元素。例如,如果您有重复项会发生什么。 例如一侧有1个div元素,另一侧有2个div元素。你将如何匹配哪些div元素匹配?
您会在比较字中找到很多其他复杂的问题。我根据经验说话(我的工作的一部分是保持我的公司文本比较引擎)。
答案 10 :(得分:0)
答案 11 :(得分:0)
看看超越比较。它具有XML比较功能,可以帮助您。
答案 12 :(得分:0)
您可能还必须考虑“内容”本身可能包含额外的标记,因此在进行比较之前,可能需要删除某些元素中的所有内容(例如具有特定ID或类的<div>
) 。例如:
<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>
答案 13 :(得分:0)
我会使用(或贡献)html5lib
及其SAX输出。只需压缩2个SAX流,寻找不匹配的内容,并突出显示整个相应的子树。
答案 14 :(得分:0)
Pretty Diff可以做到这一点。它将仅比较代码结构,无论与空格,注释甚至内容的差异如何。请务必选中“规范内容和字符串文字”选项。
答案 15 :(得分:-1)
如果我这样做,首先我会学习HTML。 (^ - ^)然后我会构建一个剥离所有实际内容的工具,然后将其保存为文件,以便通过WinDiff(或其他合并工具)进行管道传输。
答案 16 :(得分:-2)
在浏览器中打开每个页面并将其另存为.htm文件。比较两个使用windiff。