如何让我的XPath只在每个表中搜索?

时间:2016-10-05 19:35:37

标签: c# xpath html-agility-pack

我有一些看起来像这样的HTML:

<table class="resultsTable">
    <tbody>
        <tr class="even">
            <td width="35%"><strong>Name</strong></td>
            <td>ACME ANVILS, INC</td>
        </tr>
    </tbody>
</table>

以及一些看起来像这样的C#代码:

var name = document.DocumentNode
                   .SelectSingleNode("//*[text()='Name']/following::td").InnerText

幸福地回归

ACME ANVILS, INC.

然而,有一个新的皱纹。相关页面现在返回多个结果:

<table class="resultsTable">
    <tbody>
        <tr class="even">
            <td width="35%"><strong>Name</strong></td>
            <td>ACME ANVILS, INC.</td>
        </tr>
    </tbody>
</table>
<table class="resultsTable">
    <tbody>
        <tr class="even">
            <td width="35%"><strong>Name</strong></td>
            <td>ROAD RUNNER RACES, LLC</td>
        </tr>
    </tbody>
</table>

现在我正在使用

var tables = document.DocumentNode.SelectNodes("//table/tbody");
foreach (var table in tables)
{
    var name = table.SelectSingleNode("//*[text()='Name']/following::td").InnerText;
    ...
}

失败了,因为SelectSingleNode返回null。

如何让我的XPath实际返回结果,只在我选择的特定表中搜索?

1 个答案:

答案 0 :(得分:2)

增加第二张表后,需要进行两项调整:

  1. 更改绝对XPath,

    //*[text()='Name']/following::td
    

    相对于当前tabletbody元素的一个:

    .//*[text()='Name']/following::td
    
  2. 帐户现在有多个td元素 following::轴。

    要么抓住第一个,

    (.//*[text()='Name']/following::td)[1]
    

    或者更好的是,组合使用following-sibling::轴 对td的字符串值进行测试,而不是对文本节点进行测试,该测试可能隐藏在插入的格式元素下面:

     .//td[.='Name']/following-sibling::td
    

    另见Difference between Testing text() nodes vs string values in XPath