2014-04-23 43 views
5

我寫簡單的屏幕在C#刮方案,爲此,我需要選擇所有輸入的放在一個名爲「aspnetForm」單一形式的內部不工作(有在頁面上2種形式,而且我不想從另一個輸入中獲得輸入),並且此表單中的所有輸入都放置在不同的表格,div中,或者僅在此表單的第一個子級別中。在HTMLAgilityPack的XPath選擇的預期

所以我寫的非常簡單的XPath查詢:

//form[@id='aspnetForm']//input 

它的作品如預期在我測試器(Chrome,IE,Firefox)的所有瀏覽器 - 它返回我想要什麼。

但是在HTMLAgilityPack中它根本不起作用 - SelectNodes總是返回NULL。

我爲測試編寫此查詢工作正常,但返回不是我想要的。首先選擇所有輸入的是第一孩子的我的形式,而第二隻迴歸的形式:

//form[@id='aspnetForm']/input 
//form[@id='aspnetForm'] 

是的,我知道我可以只從上次查詢枚舉節點,或作出它的結果是另一個的SelectNodes,但我真的不想這樣做。我想使用與瀏覽器中相同的查詢。

目前XPath中斷了HTMLAgilityPack?有什麼替代XPath實現C#?

using HtmlAgilityPack; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace HtmlAGPTests 
{ 
    [TestClass] 
    public class XPathTests 
    { 
     private const string html = 
       "<form id=\"aspnetForm\">" + 
       "<input name=\"first\" value=\"first\" />" + 
       "<div>" + 
        "<input name=\"second\" value=\"second\" />" + 
       "</div>" + 
       "</form>"; 

     private static HtmlNode GetHtmlDocumentNode() 
     { 
      var document = new HtmlDocument(); 
      document.LoadHtml(html); 
      return document.DocumentNode; 
     } 

     [TestMethod] 
     public void TwoLevelXpathTest()  // fail - nodes is NULL actually. 
     { 
      var query = "//form[@id='aspnetForm']//input"; // what i want 
      var documentNode = GetHtmlDocumentNode(); 

      var inputNodes = documentNode.SelectNodes(query); 

      Assert.IsTrue(inputNodes.Count == 2); 
     } 

     [TestMethod] 
     public void TwoSingleLevelXpathsTest()  // works 
     { 
      var formQuery = "//form[@id='aspnetForm']"; 
      var inputQuery = "//input"; 
      var documentNode = GetHtmlDocumentNode(); 

      var formNode = documentNode.SelectSingleNode(formQuery); 
      var inputNodes = formNode.SelectNodes(inputQuery); 

      Assert.IsTrue(inputNodes.Count == 2); 
     } 

     [TestMethod] 
     public void SingleLevelXpathTest()  // works 
     { 
      var query = "//form[@id='aspnetForm']"; 
      var documentNode = GetHtmlDocumentNode(); 

      var formNode = documentNode.SelectSingleNode(query); 

      Assert.IsNotNull(formNode); 
     } 

    } 
} 
+0

.NET已建成的XPath,直接用於通過HtmlAgilityPack(HAP沒有實現自己的XPath引擎)。實際上,HAP的XPath對我來說工作得很好,所以我建議先懷疑別的東西。 – har07

+0

嘗試保存'HtmlDocument',然後檢查保存的文件是否包含預期的HTML格式。 – har07

+1

@ har07,它包含 - 我發佈之前測試過的問題。此外,「骯髒的解決方法」方法的作品,所以它絕對不是輸入問題。增加了測試代碼來提問,這樣你就可以自己測試它 - 它不像預期的那樣工作。 – rufanov

回答

4

在測試中意外的行爲發生,因爲HTML包含<form>元素:

UPDATE:測試代碼。下面是相關討論:

Ariman:「我發現,分析任何節點沒有任何子節點之後所創建的形式應爲(,,等)內的所有節點,因爲它是。兄弟姐妹而不是孩子

VikciaR: 「在HTML規範的表單標籤可以重疊,所以Htmlagilitypack處理這個節點有點不同......」

[CodePlex discussion : No child nodes for FORM objects]

而且通過VikciaR還有的建議,嘗試修改你的測試代碼初始化是這樣的:

private static HtmlNode GetHtmlDocumentNode() 
{ 
    var document = new HtmlDocument(); 
    document.LoadHtml(html); 

    //execute this line once 
    HtmlNode.ElementsFlags.Remove("form"); 

    return document.DocumentNode; 
} 

邊注:測試方法TwoSingleLevelXpathsTest()inputQuery值應爲.//input。請注意開頭的點(.)以指示此查詢與當前節點相關。否則,它會從根本上進行搜索,忽略前者formQuery(不點,你可以改變formQuery到任何東西,只要它沒有返回null,則inputQuery總是會返回相同的結果)。

+2

默認情況下有點奇怪的行爲..但無論如何,謝謝!有用! – rufanov