Я использую HTMLAgilityPack в приложении C # WPF для прокрутки некоторых якорных тегов на локальной 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, я хочу найти субтитры1. Аналогично для link2 и link3. Но для link4 и link5 я хочу найти субтитры2. Я использую этот оператор 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 для возвращения ближайшего родственника?
локатор для получения субтитров по тексту ссылки ('link4')
(//a[text()='link5']/preceding::tr[.//a[@class='subtitle']])[last()]
логика:
//a[text()='link4']
- получить элемент связанным текстом
//a[text()='link4']/preceding::tr
- поиск всех tr родителей
[.//a[@class='subtitle']]
- получить первый родитель, содержащий тегa
сsubtitle
класса'
(someLocator)[last()]
- получить последний элемент, соответствующий локатору, в нашем случае - получить последний родительский тегa
с классом 'subtitle
'
другой вариант - сначала поиск tr
а a
элементе
(//tr[.//a[text()='link5']]/preceding-sibling::tr//a[contains(@class,'subtitle')])[last()]
мы надеемся, что это поможет кому-то получить логику для создания локаторов
Попробуйте использовать xpath:
//a[@href='<your_input>']/preceding-sibling::tr[.//a[@class='subtitle']][1]
где <your_input>
может быть link1.pdf
на link5.pdf