2012-05-30 36 views
2

我在使用HtmlAgilityPack的XPath選擇方面遇到了很多麻煩。使用HtmlAgilityPack計算特定的子節點

我想選擇所有li元素(如果存在的話)嵌套在另一個li女巫有a標籤與id="menuItem2"。 這是HTML樣本:

<div id="menu"> 
    <ul> 
    <li><a id="menuItem1"></a></li> 
    <li><a id="menuItem2"></a> 
     <ul> 
      <li><a id="menuSubItem1"></a></li> 
      <li><a id="menuSubItem2"></a></li> 
     </ul> 
    </li> 
    <li><a id="menuItem3"></a></li> 
    </ul> 
</div> 

這是我被使用XPath。當我失去這部分/ul/li時,它會得到我想要的a標記,但我需要他的後代...此XPath始終返回空值。

string xpathExp = "//a[@id='" + parentIdHtml + "']/ul/li"; 
HtmlNodeCollection liNodes = htmlDoc.DocumentNode.SelectNodes(xpathExp); 

回答

0

試試這個爲你的XPath:

string xpathExp = "//li[a/@id='" + parentIdHtml + "']/ul/li"; 

的問題是,你是選擇a節點本身,它沒有ul孩子。您需要先選擇li節點,然後過濾其a孩子。

1

以下XPath應該可以工作。

string xpathExp = "//li/a[@id='" + parentIdHtml + "']/following-sibling::ul/li"; 
0

XPath太混亂了。您正在使用HtmlAgilityPack,您可能還會利用LINQ。

//find the li -- a *little* complicated with nested Where clauses, but clear enough. 
HtmlNode li = htmlDoc.DocumentNode.Descendants("li").Where(n => n.ChildNodes.Where(a => a.Name.Equals("a") && a.Id.Equals("menuItem2", StringComparison.InvariantCultureIgnoreCase)).Count() > 0).FirstOrDefault(); 
IEnumerable<HtmlNode> liNodes = null; 
if (li != null) 
{ 
    //Node found, get all the descendent <li> 
    liNodes = li.Descendants("li"); 
} 
+1

在這種情況下,我會說使用LINQ這裏是非常混亂。我發現使用XPath比寫出LINQ查詢要好得多,尤其是在複雜的情況下。 –

+0

你投票給我,因爲你認爲XPath更清晰謝謝Linq?尤其*當它很複雜時?大聲笑... –

+2

我沒有倒下你......我也沒有看到這樣做的理由。這是一個很好的答案,我沒有問題。在你投降之前,我很好地評論了這個評論。讓你的事實直LOL ... –

0

從你的描述,我認爲你要選擇包含<a>標籤與IDS menuSubItem1menuSubItem2兩個<li>元素?

如果是這樣,那麼這是你所需要的

//li[a/@id="menuItem2"]//li