2010-06-23 287 views
0

我在解析html中的輸入標籤子窗體時出現問題。我可以使用// input [@type]從根目錄解析它們,但不能作爲特定節點的子節點。使用HtmlAgilityPack解析節點的子節點的問題

下面是一些代碼,說明了這個問題:

private const string HTML_CONTENT = 
     "<html>" + 
     "<head>" + 
     "<title>Test Page</title>" + 
     "<link href='site.css' rel='stylesheet' type='text/css' />" + 
     "</head>" + 
     "<body>" + 
     "<form id='form1' method='post' action='http://www.someplace.com/input'>" + 
     "<input type='hidden' name='id' value='test' />" + 
     "<input type='text' name='something' value='something' />" + 
     "</form>" + 
     "<a href='http://www.someplace.com'>Someplace</a>" + 
     "<a href='http://www.someplace.com/other'><img src='http://www.someplace.com/image.jpg' alt='Someplace Image'/></a>" + 
     "<form id='form2' method='post' action='/something/to/do'>" + 
     "<input type='text' name='secondForm' value='this should be in the second form' />" + 
     "</form>" + 
     "</body>" + 
     "</html>"; 

public void Parser_Test() 
    { 
     var htmlDoc = new HtmlDocument 
     { 
      OptionFixNestedTags = true, 
      OptionUseIdAttribute = true, 
      OptionAutoCloseOnEnd = true, 
      OptionAddDebuggingAttributes = true 
     }; 

     byte[] byteArray = Encoding.UTF8.GetBytes(HTML_CONTENT); 
     var stream = new MemoryStream(byteArray); 
     htmlDoc.Load(stream, Encoding.UTF8, true); 
     var nodeCollection = htmlDoc.DocumentNode.SelectNodes("//form"); 
     if (nodeCollection != null && nodeCollection.Count > 0) 
     { 
      foreach (var form in nodeCollection) 
      { 
       var id = form.GetAttributeValue("id", string.Empty); 
       if (!form.HasChildNodes) 
        Debug.WriteLine(string.Format("Form {0} has no children", id)); 

       var childCollection = form.SelectNodes("input[@type]"); 
       if (childCollection != null && childCollection.Count > 0) 
       { 
        Debug.WriteLine("Got some child nodes"); 
       } 
       else 
       { 
        Debug.WriteLine("Unable to find input nodes as children of Form"); 
       } 
      } 
      var inputNodes = htmlDoc.DocumentNode.SelectNodes("//input"); 
      if (inputNodes != null && inputNodes.Count > 0) 
      { 
       Debug.WriteLine(string.Format("Found {0} input nodes when parsed from root", inputNodes.Count)); 
      } 
     } 
     else 
     { 
      Debug.WriteLine("Found no forms"); 
     } 
    } 

什麼是輸出:

Form form1 has no children 
Unable to find input nodes as children of Form 
Form form2 has no children 
Unable to find input nodes as children of Form 
Found 3 input nodes when parsed from root 

我會想到的是,Form 1和Form既能有孩子和輸入[@type ]將能夠找到2個節點的form1和1的form2

是否有一個特定的配置設置或方法,我沒有使用,我應該是?有任何想法嗎?

感謝,

史蒂夫

回答

2

好吧,我已經放棄了HtmlAgilityPack現在。似乎在圖書館裏還有更多的工作要做,爲了解決這個問題,我已經將代碼移到使用這裏的SGMLReader庫中:http://developer.mindtouch.com/SgmlReader

使用這個庫,我的所有單元測試都能正常通過,並且示例代碼按預期工作。

4

退房的HtmlAgilityPack網站上的這個話題 - http://htmlagilitypack.codeplex.com/workitem/21782

這就是他們所說的話:

這是不是一個錯誤,而是一個功能是可配置的。 FORM被這樣對待,因爲許多HTML頁面都有重疊的表單,因爲這實際上是原始HTML的一個(強大的)功能。既然XML和XHTML存在,所有人都認爲重疊是一個錯誤,但它不是(在HTML 3.2中)。 檢查HtmlNode.cs文件,並修改ElementsFlags集合(或在運行時做到這一點,如果你喜歡)

要修改HtmlNode.cs文件中註釋掉以下行 -

ElementsFlags.Add("form", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty); 
+1

對於那些誰不想更改Html Agility Pack代碼:HtmlNode.ElementsFlags.Remove(「form」); – Doug 2011-09-10 16:20:15

+0

更多在這裏:http://stackoverflow.com/questions/4218847/htmlagilitypack-does-form-close-itself-for-some-reason – 2012-05-07 07:09:49

+3

我希望我可以多次投票。這個「特徵」鼓勵陷入失敗的陷阱。 – MatthewMartin 2013-05-08 21:48:44