2011-03-01 113 views
0

Heyy球員,我需要確定給定的HTML文檔是否格式正確。
我只需要一個簡單的實現,只使用Java核心API類,即沒有像JTIDY之類的第三方東西。HTML格式良好解析器

實際上,確切需要的是掃描標籤列表的算法。如果它找到一個開放的標籤,並且下一個標籤不是其對應的關閉標籤,那麼它應該是另一個開放標籤,而它的下一個標籤應該有它的關閉標籤,如果不是,它應該是另一個開放標籤,然後其下一個對應的關閉標記,以及相反順序的先前打開標記的關閉標記在列表中一個接一個地出現。如果列表符合此順序,則返回true或否則爲false。我已經編寫了將標籤轉換爲關閉標籤的方法。

這裏是我已經開始工作的骨架代碼。它不太整潔,但它應該給你們一個我想要做的事情的基本概念。

public boolean validateHtml(){ 

    ArrayList<String> tags = fetchTags(); 
    //fetchTags returns this [<html>, <head>, <title>, </title>, </head>, <body>, <h1>, </h1>, </body>, </html>] 

    //I create another ArrayList to store tags that I haven't found its corresponding close tag yet 
    ArrayList<String> unclosedTags = new ArrayList<String>(); 

    String temp; 

    for (int i = 0; i < tags.size(); i++) { 

     temp = tags.get(i); 

     if(!tags.get(i+1).equals(TagOperations.convertToCloseTag(tags.get(i)))){ 
      unclosedTags.add(tags.get(i)); 
      if(){ 

      } 

     }else{ 
      return true;//well formed html 
     } 
    } 

    return true; 
} 
+4

我強烈建議爲此使用第三方庫。除非這是一項學術活動,否則這是不值得的。邊緣情況? '
',自閉標籤,不同的文檔類型... – 2011-03-01 20:17:48

+1

[How to validate HTML from Java?](http://stackoverflow.com/questions/4392505/how-to-validate-html-from- java) – 2011-03-01 20:18:37

+2

我發現你已經付出了一些努力(作業)?幹得好!但是,我們儘量不要「發送da codez」。有沒有我們可以幫助你的具體問題,而不僅僅是完成你的算法? – 2011-03-01 20:20:16

回答

0

兩個想法。首先,也許你可以逃避在HTML上使用XML解析器?可能更容易,而且耗時更少。

我對此沒有太多的想法,但對我來說,這聽起來像遞歸和堆棧將是一條路。像

public myClass(String htmlInput) 
{ 
    openedTags = new Stack<String>(); 
    this.htmlInput = htmlInput; 
} 
public boolean validate() 
{ 
    return validate(this.htmlInput); 
} 
private boolean validate(String html) 
{ 
    boolean result = true; 
    String curTag; 
    while(htmlLeft)  //worker loop 
    { 

     if(isOneOffTag(curTag))     //matches <tags /> 
      continue; 
     else if(isOpenTag(curTag))    //matches <tags> 
     { 
      openedTags.push(curTag); 
      if(!validate(innerHtml)) 
       return false; 
     } 
     else if(isCloseTag(curTag))    //matches </tags> 
     { 
      String lastTag = (String)openedTags.peek(); 
      if(!tagIsSimiliar(curTag, lastTag)) 
       return false; 
      openedTags.pop(); 
     } 
    } 


    return result; 
} 
private String nextTag(){return null;} 
private boolean isOpenTag(String tag){ return true;} 
private boolean isCloseTag(String tag){ return true;} 
private boolean isOneOffTag(String tag){ return true;} 
private boolean tagIsSimiliar(String curTag, String lastTag){return true;} 

*編輯1:可能應該推入堆棧。

**編輯2:我想這裏的問題是確定何時單獨返回一個布爾值,你已經離開了。這需要某種指針,以便你知道你從哪裏離開。儘管我相信這個想法仍然有效。

+0

僅供參考,「一次性標籤」的通用術語是「自動結束標籤」。 – 2011-03-01 21:42:09

+0

hmmn,這是你在這裏開發的一個有趣的算法,很快,很酷,我想我開始明白你在這裏要做什麼。但我不完全理解「htmlLeft」和「innerHtml」這兩個術語的含義,請詳細說明。 – kooldave98 2011-03-01 22:19:18

+0

嗯,是的,我不認爲我在這上面花了足夠的時間。剩下的Html只是外部工作循環,只要有剩餘的html可以解析,它就會一直運行。我會離開這個取決於你。 innerHtml是一個術語,我從C#拿起,我相信這將指這是innerHtml。 這個問題將只會通過內部的HTML,這可能是更多的努力,那麼它的價值。如果你通過錯誤的innerhtml,你將不得不使用一個複雜的檢查系統來彌補。 去掉遞歸,它應該工作正常。我真的很喜歡遞歸的想法。 – Highstead 2011-03-02 14:23:50