Lets say I have this html (ignore tags names):
<div>
<card>
<h2>1</h2>
</card>
<footer>
<p>text 1</p>
</footer>
</div>
<div>
<card>
<h2>2</h2>
</card>
<footer>
<p>text 2</p>
</footer>
</div>
<div>
<card>
<h2>3</h2>
</card>
<footer>
<p>text 2</p>
</footer>
</div>
and I want to select p tag that have an h2 value of 2 (I will select p with text 2)
if I use this expression //h2[text()="2"]/../following::footer/p I will get 2 p tags.
How do I select only the p tag with cousin h2 value of 2 ?
EDIT: Robbie Averill answer was the first to work, but you should check other answers they are very good too.
You can navigate from the h2 matched up to the div that contains the element you want, then target footer/p elements from there:
//h2[text()="2"]/../../footer/p
Try to use below XPath to select required element:
//card[h2="2"]/following-sibling::footer/p
This XPath,
//div[card/h2="2"]/footer/p
will select footer/p cousins of card/h2 elements with string values of 2.
Related
Say I have the following XML:
<body>
<div id="global-header">
header
</div>
<div class="a">
<h3>some title</h3>
<p>text 1</p>
<p>text 2</p>
<p>text 3</p>
</div>
</body>
I want to
find any <p> node whose value is "text 2", and then
find all the nodes that precede this particular <p> but are also descendants of the <div class='a'> node.
The desired output should look like:
<h3>some title</h3>
<p>text 1</p>
The caveat is that the preceding nodes may contain arbitrary node type, not only <h3> and <p>, as in the above case.
My first try:
.//p[text()="text 2"]/preceding::*
Unfortunately, this will also select <div id="global-header">, which is not desired.
You need to use preceding-sibling to select nodes that are children of the same parent instead of preceding:
.//p[text()="text 2"]/preceding-sibling::*
Only requirement: it needs to refer to the thread-navigation class, because that page has many other pagination elements
<section id="thread-navigation" class="group">
<div class="float-left">
<div class="pagination talign-mleft">
<span class="pages">Pages (6):</span>
<span class="pagination_current">1</span>
2
3
4
5
6
Next ยป //<--- this one
</div>
</div>
</section>
I was trying something like this:
r.xpath('//*[#class="thread-navigation" and contains (., "Next")]').get()
But it always returns None
Thank you
You are not referring to an #class attribute, but rather to an #id attribute with the value thread-navigation. So try this XPath-1.0 expression:
r.xpath('//a[ancestor::*/#id="thread-navigation" and contains (text(), "Next")]/#href').get()
Its result is
I want this text?page=2
This xpath:
'//section[#id="thread-navigation"]//a/#href'
In the following html tags:
<div>
<div>
<h3>
<a href='http://Ali.org'></a>
</h3>
<div>
<p>
<a href='http://Mohammad.org'></a>
</p>
</div>
</div>
<div>
<h4>
<a href='http://Ali.org'></a>
</h4>
<p>
<a href='http://Mohammad.org'></a>
</p>
</div>
</div>
I want to select two 'a' tags 'http://Ali.org' & 'http://YaALi.org'. By the following, I can:
//div//a[not(parent::*[not(following-sibling::*)])]
But what about a simpler XPath?
By the following, all of 'a' tags will be selected since they are all the first child of their parents:
//div/div//a[1]
Or by the following, just the first 'a' tag will be selected:
(//div//a)[1]
I want to select 'a' tags that are the first in the 'a' tags of div elements...
// in the middle of a path is an abbreviation for descendant-or-self::node(), so if you do
//div/div//a[1]
this effectively means
//div/div/descendant-or-self::node()/a[1]
This picks the first child a of all descendant nodes. What you want is:
//div/div/descendant::a[1]
which will pick the first descendant a.
I have the following html:
<div class="stack">
<h2 class="overflow">
<img src="http:..">
text
</h2>
<div class="sublist">
<table>
...
</table>
</div>
<h2 class="overflow">
link
</h2>
</div>
As you can see, the .sublist div always follows a with and some text, it's like the div is a sublist of the h2(the h2 is the title of the sublist). The other contains an anchor tag.
I'd like to get all the h2 tags which preceeds the div .sublist.
This is my current xpath clause:
//div[#class="stack"]/h2/*[not(descendant::a)]
And I end up getting different elements(a, div, img) but the h2 elements.
I'd like to get all the h2 tags which preceeds the div .sublist.
How about:
//div[class="sublist"]/preceding-sibling::h2
Try preceding-sibling:
//div[#class="stack"]/div[#class="sublist"]/preceeding-sibling::*
Given following markup
<div>
<a>Username1</a>
</div>
<div>
<button>Unblock</button>
</div>
<div>
<a>Username2</a>
</div>
<div>
<button>Unblock</button>
</div>
<div>
<a>Username3</a>
</div>
<div>
<button>Unblock</button>
</div>
How do I select button element which is a cousin of a element with text Username2?
I can select the a element with //a[contains(., 'Username2')], so I thought that //a[contains(., 'Username2')]/following-sibling::/div/button would select the correct button, but that does not work. I think that it's not even valid XPATH.
You were close:
//a[contains(., 'Username2')]/../following-sibling::div[1]/button
To navigate to the cousin you first have to go to the parent (..) and then to its sibling.
Note that the following-sibling:: axis selects all following siblings, not only the first one. This means you must use [1] if you just want the first.
This would also work:
//a[. = 'Username2']/../following-sibling::div[1]/button
So would this:
//div[a = 'Username2']/following-sibling::div[1]/button