用于查找最近的兄弟

时间:2017-06-26 16:19:49

标签: c# xpath html-agility-pack

我在C#WPF应用程序中使用HTMLAgilityPack来遍历本地HTML页面中的一些锚标记并提取href属性。这很好用,但我需要在HTML文档中找到锚点所在的标题(这也是一个锚标记)。这应该很容易与XPath一起使用,但我似乎无法获得适用于所有场景的语句。

这是我的HTML示例(我无法控制):

<html>
    <body>
        <table>
            <tr>
                <td><div><a href="#maintitle" class="title">maintitle</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle1" class="subtitle">subtitle1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link1.pdf">link1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link2.pdf">link2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link3.pdf">link3</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle2" class="subtitle">subtitle2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link4.pdf">link4</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link5.pdf">link5</a></div></td>
            </tr>
        </table>
    </body>
</html>

找到link1后,我想找到subtitle1。同样适用于link2和link3。但对于link4和link5,我想找到subtitle2。我正在使用这个XPath语句(第一部分就是为了模拟一个锚标签的选择,我已经在线上使用了XPath评估器https://www.freeformatter.com/xpath-tester.html):

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr//a[@class='subtitle']

这适用于link1到link3,但对于link4和link5,它返回subtitle1和subtitle2。将[1]添加到preceding-sibling::t会为link4修复它,但会将其分解为link2,link3和link5:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[1]//a[@class='subtitle']

我还尝试将last()添加到preceding-sibling::t,但这导致没有找到任何链接:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[last()]//a[@class='subtitle']

我确信这是一个简单的解决方案,但我绝不能胜任XPath,所以我很难挣扎。如何获取原始XPath语句以返回最近的兄弟姐妹?

2 个答案:

答案 0 :(得分:3)

通过链接文字获取字幕的定位器(&#39; link4&#39;)

  

(//a[text()='link5']/preceding::tr[.//a[@class='subtitle']])[last()]

逻辑:

  

//a[text()='link4'] - 按链接文字获取元素

     

//a[text()='link4']/preceding::tr - 搜索所有tr父母

     

[.//a[@class='subtitle']] - 获取包含标记a的第一个父级   课程&#39; subtitle&#39;

     

(someLocator)[last()] - 获取最后一个匹配定位符的元素,在我们的示例中 - 使用类&#39; a&#39;

获取包含标记subtitle的最后一个父元素

另一种选择 - 最初搜索tr而不是a元素

(//tr[.//a[text()='link5']]/preceding-sibling::tr//a[contains(@class,'subtitle')])[last()]

希望它能帮助任何人获得逻辑构建定位器

答案 1 :(得分:0)

尝试使用xpath:

//a[@href='<your_input>']/preceding-sibling::tr[.//a[@class='subtitle']][1]

其中<your_input>可以是link1.pdflink5.pdf