【发布时间】:2017-11-29 13:19:48
【问题描述】:
我在 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。链接 2 和链接 3 也是如此。但是对于link4和link5,我想找subtitle2。我正在使用这个 XPath 语句(第一部分只是为了模拟锚标记的选择,我一直在使用在线 XPath 评估器https://www.freeformatter.com/xpath-tester.html):
//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr//a[@class='subtitle']
这适用于链接 1 到链接 3,但对于链接 4 和链接 5,它会返回 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 语句返回最近的兄弟?
【问题讨论】:
标签: c# xpath html-agility-pack