2008-09-17 75 views
11

this post我問是否有任何工具比較2個HTML頁面的結構(不是實際內容)。我問,因爲我收到來自我們的設計師的HTML模板,並經常錯過我的實現中的小的格式更改。然後,我浪費了幾個小時的設計師時間篩選我的頁面,以查找我的錯誤。關於如何構建HTML Diff工具的建議?

該主題提供了一些很好的建議,但沒有什麼符合該法案。 「好吧,那麼」,我想,「我會自己動手一個,我是一箇中等體面的開發者,對吧?」

好吧,一旦我開始考慮這個問題,我無法弄清楚如何去做。我可以很容易地開發一個數據驅動的網站,或者做一個CMS實施,或者整天扔出和扔出BizTalk文檔。無法開始弄清楚如何比較HTML文檔。

嗯,當然,我必須讀取DOM,並遍歷節點。我必須將結構映射到一些數據結構(如何?),然後比較它們(如何?)。這是一個像我曾嘗試過的開發任務。

所以現在我已經發現了我的知識中的一個弱點,我更加想要解決這個問題。有關如何開始的任何建議?

澄清:實際內容是不是我想要的比較 - 創造性的球員填補他們的頁面與 Lorem存有,我用真正的內容。相反,我想比較結構:

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

不同的是

 

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

回答

-2

打開瀏覽器中的每一頁,並將其保存爲.htm文件。比較兩個使用windiff。

+0

我覺得OP的問題是,他已經添加內容到頁面,在這個過程中可能會意外地改變了一些標記。所以當他想要的是標記差異時,差異會將所有內容視爲差異。 – EBGreen 2008-09-17 19:51:49

1

@Mike - 這將比較一切,包括頁面的內容,這是不希望的原始海報通緝。

假設您可以訪問瀏覽器的DOM(通過編寫Firefox/IE插件或其他),我可能會將所有HTML元素放入一棵樹中,然後比較這兩棵樹。如果標籤名稱不同,則節點不同。你可能想在某個時候停止枚舉(你可能不關心跨度,粗體,斜體等 - 可能只是擔心div),因爲一些標籤實際上是內容而不是結構頁。

+0

雖然任何結構性差異都會出現在windiff中。我認爲這會更難解決。 – Mike 2008-09-17 19:56:55

+0

的確如此。我想我只是假設OP希望能夠隱藏/忽略頁面內容,以便更容易地看到結構的差異。 – Andy 2008-09-17 23:43:03

2

DOM是一種數據結構 - 它是一棵樹。

0

我不知道任何工具,但我知道有一個簡單的方法來做到這一點:

  • 首先,使用正則表達式工具在HTML文件中去掉所有文本。您可以使用此正則表達式搜索文本(?<=^|>)[^><]+?(?=<|$),並用空字符串("")替換它們,即刪除所有文本。完成此步驟後,您將擁有所有HTML標記標記。那裏有很多免費的正則表達式工具。
  • 然後,重複原始HTML文件的第一步。
  • 最後,您使用diff工具比較兩組HTML標記。這將顯示一套和另一套之間缺少的東西。
2

通過以下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"; 
    } 
} 
+0

這實際上是我會做的。它將這兩個文件縮減爲其基本元素,將您不關心的內容(本例中的文本)規範化,然後利用現成的工具進行實際工作。 – 2008-09-22 02:21:19

0

這是一個很好的開始。一些更多的澄清/評論:

  • 我可能不關心的ID,因爲.NET會損壞它們
  • 一些結構將是一箇中繼器或其他這樣的控制,所以我可能最終不得不更多或更少的重複元素

進一步思考: 我認爲一個好的開始將假設html是符合XHTML的。然後,我可以推斷模式(使用新的.net XmlSchemaInference方法),然後區分模式。然後我可以看看差異並考慮它們是否有意義。

1

如果我是TACKE這個問題,我會做到這一點:

了某種對HTML頁面的DOM的
  1. 計劃。從輕量級開始,然後根據需要添加更多。我會爲數據結構使用複合模式。即每個元素都有基類類型的子集合。
  2. 創建一個解析器來解析html頁面。
  3. 使用解析器加載HTML元素到DOM。
  4. 將頁面加載到DOM後,您就可以獲得html頁面結構的分層快照。
  5. 繼續遍歷兩邊的每個元素直到DOM結束。當你遇到不匹配的元素類型時,你會在結構中找到差異。

在你的例子中,你只能在一邊加載一個div元素對象,另一方面你會有一個div元素對象加載1個子元素類型爲paragraph元素。激發你的迭代器,首先你會匹配div元素,第二個迭代器,你會匹配段沒有。你有你的結構差異。

1

我認爲上面的一些建議沒有考慮到HTML中兩個頁面之間存在其他標記,這些標記在文本上會有所不同,但生成的HTML標記在功能上是等效的。 Danimal將控件ID列爲示例。

以下兩個標記是functionlly相同,但會出現,如果你只是比較標籤不同:

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

我要建議Danimal編寫一個HTML轉換看起來對HTML標籤和轉換都docs轉化爲兩者的簡化版本,省略ID標籤和您指定爲不相關的任何其他標籤。這可能必須是一個正在進行的工作,因爲您忽略了某些屬性/標籤,然後運行到您也不想忽略的新屬性。然而,我喜歡使用XmlSchemaInterface將其歸結爲XML模式,然後使用瞭解XML規則的diff工具。

0

我的建議只是做到這一點的基本方式......當然,要解決您提到的問題,必須在此處應用其他規則......在你的情況下,我們得到了一個匹配的div元素,然後應用屬性/屬性匹配規則以及什麼不是...

說實話,有很多複雜的規則需要應用於比較,它不僅僅是一個簡單的匹配元素到另一個元素。例如,如果你有重複,會發生什麼。 例如一邊有1個div元素,另一邊有2個div元素。你將如何匹配哪些div元素匹配在一起?

還有很多其他複雜的問題,你會發現比較詞。我根據經驗說話(我的工作的一部分是保持我的公司文本比較引擎)。

1

請參閱http://www.semdesigns.com/Products/SmartDifferencer/index.html瞭解通過語言語法進行參數化的工具,並根據語言元素(標識符,表達式,語句,塊,方法等)插入,刪除,移動,替換或標識符生成增量始終如一地取代它。該工具忽略空格重新格式化(例如,不同的換行符或佈局)和語義上不可區分的值(例如,它知道0x0F和15是相同的值)。 這可以應用於使用HTML解析器的HTML。

編輯:9/12/2009。我們使用HTML編輯器構建了一個實驗性的SmartDiff工具。

-1

如果我要這樣做,首先我會學習HTML。 (^ - ^)然後,我將構建一個工具,去除所有實際內容,然後將其保存爲文件,以便通過WinDiff(或其他合併工具)進行管道傳輸。

0

看看超越比較。它有一個XML比較功能,可以幫助你。

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> 
0

我會使用(或向)html5lib及其SAX輸出。只需通過2個SAX流查找不匹配,並突出顯示整個相應的子樹。

0

Pretty Diff可以做到這一點。它只會比較代碼結構,而不考慮空白區域,評論甚至內容的差異。只需確保選中「Normalize Content and String Literals」。

http://prettydiff.com/