从所选节点进一步遍历xpath

时间:2014-09-12 08:40:53

标签: c# .net xpath html-agility-pack

我有以下html结构

<div class="ac_x">
    <h3>
        <a href="">Title</a>                
    </h3>
    <a class="">
        <img title="" />
    </a>
    <dl>
        <dt class="">Person</dt>
        <dd class="">
        <dt class="ac_i_ard">Address</dt>
        <dd class="ac_i_ard">
            <a href="">Target text</a>
        </dd>
    </dl>
</div>

我正在使用

选择标题
 var nodes = htmlDoc.DocumentNode.SelectNodes(@"//div[@class='ac_x']/h3/a")
                         .Cast<HtmlAgilityPack.HtmlNode>().
                         .Select ....

现在我想以编程方式选择<dd class="ac_i_ard">下的目标文字

我试过

node[0].SelectSingleNode(@"../dl/dd[2]/a");  

但显然我没有选择节点

Object reference not set to an instance of an object.

如何从已选择的节点以编程方式选择节点(目标文本)?

3 个答案:

答案 0 :(得分:1)

你可以使用

../../dl/dd[@class='ac_i_ard']/a

../following-sibling::dl/dd[@class='ac_i_ard']/a

答案 1 :(得分:1)

var rootNodes = htmlDoc.DocumentNode.SelectNodes(@"//div[@class='ac_x']")
foreach(var n in rootNodes)
{
     var titleNode = n.SelectSingleNode(@"h3/a");
     var ddNodes = n.SelectNodes(@"dl/dd[@class='ac_i_ard']]/a");
}

答案 2 :(得分:1)

另一个问题是第一个<dd>标记未关闭。因此,所有以下兄弟都被HtmlAgilityPack解释为子。这就是为什么以下工作的原因:

var n = node.SelectSingleNode(@"../following-sibling::dl/dd/dd[@class='ac_i_ard']/a");

或者更简单的方法:

var n = node.SelectSingleNode(@"../following-sibling::dl//dd[@class='ac_i_ard']/a");

[.NET Fiddle demo]