Use xpath or xquery to show text in title attribute - xpath

I'd like to use xquery (I believe) to output the text from the title attribute of an html element.
Example:
<div class="rating" title="1.0 stars">...</div>
I can use xpath to select the element, but it tries to output the info between the div tags. I think I need to use xquery to output the "1.0 stars" text from the title attribute.
There's gotta be a way to do this. My Google skills are proving ineffective in coming up with an answer.
Thanks.

XPath: //div[#class='rating']/#title
This will give you the title text for every div with a class of "rating".
Addendum (following from comments below):
If the class has other, additional text in it, in addition to "rating", then you can use something like this:
//div[contains(concat(' ', normalize-space(#class), ' '), ' rating ')]
(Hat tip to How can I match on an attribute that contains a certain string?).

You should use:
let $XML := <p><div class="rating" title="2.0 stars">sdfd</div><div class="rating" title="1.0 stars">sdfd</div></p>
for $title in $XML//#title
return
<p>{data($title)}</p>
to get output:
<p>2.0 stars</p>
<p>1.0 stars</p>

Related

How to exclude a child node from xpath?

I have the following code :
<div class = "content">
<table id="detailsTable">...</table>
<div class = "desc">
<p>Some text</p>
</div>
<p>Another text<p>
</div>
I want to select all the text within the 'content' class, which I would get using this xPath :
doc.xpath('string(//div[#class="content"])')
The problem is that it selects all the text including text within the 'table' tag. I need to exclude the 'table' from the xPath. How would I achieve that?
XPath 1.0 solutions :
substring-after(string(//div[#class="content"]),string(//div[#class="content"]/table))
Or just use concat :
concat(//table/following::p[1]," ",//table/following::p[2])
The XPath expression //div[#class="content"] selects the div element - nothing more and nothing less - and applying the string() function gives you the string value of the element, which is the concatenation of all its descendant text nodes.
Getting all the text except for that containing in one particular child is probably not possible in XPath 1.0. With XPath 2.0 it can be done as
string-join(//div[#class="content"]/(node() except table)//text(), '')
But for this kind of manipulation, you're really in the realm of transformation rather than pure selection, so you're stretching the limits of what XPath is designed for.

xpath search for class and text - combine two xpath selector

I know there are tousands of simple question about xpath but i dont get it how to combine two not too simple expressions...
My xml structure:
<div class="some-container">
<div class="btn btn-blue">
<div class="btn-text"><!-- Select by class -->
<span> <!-- Select by text-->
Download
</span>
</div>
</div>
</div>
Select by class
I know achieved to select the div by searching after the class:
//*/div[contains(concat(' ', #class, ' '), ' btn-text')]
Select by text
To select also the span i know i can simply add /span but then i want to select by text.
For that usecase i got the xpath (form here):
//*/text()[normalize-space(.)='Download']/parent::*
Those selector both are working properly but i want to combine them
Search for class "btn"
Search for text inside span that exactly matches
I tried to concat like that but that dont work test-example:
//div[contains(concat(' ', #class, ' '), ' btn-text')]/text()[normalize-space(.)='Download']/parent::*
even if it'd work there is no selecting by span tag
Anyone who could help?
Your XPath is looking for a text node directly inside the div, but the text node you're looking for is inside a span. That's why it's not succeeding.
To get it to work, just change the XPath to look for the span and not the text node:
//div[contains(concat(' ', #class, ' '), ' btn-text ')]/span[normalize-space(.)='Download']

Xpath get element above

suppose I have this structure:
<div class="a" attribute="foo">
<div class="b">
<span>Text Example</span>
</div>
</div>
In xpath, I would like to retrieve the value of the attribute "attribute" given I have the text inside: Text Example
If I use this xpath:
.//*[#class='a']//*[text()='Text Example']
It returns the element span, but I need the div.a, because I need to get the value of the attribute through Selenium WebDriver
Hey there are lot of ways by which you can figure it out.
So lets say Text Example is given, you can identify it using this text:-
//span[text()='Text Example']/../.. --> If you know its 2 level up
OR
//span[text()='Text Example']/ancestor::div[#class='a'] --> If you don't know how many level up this `div` is
Above 2 xpaths can be used if you only want to identify the element using Text Example, if you don't want to iterate through this text. There are simple ways to identify it directly:-
//div[#class='a']
From your question itself you have mentioned the answer for it
but I need the div.a,
try this
driver.findElement(By.cssSelector("div.a")).getAttribute("attribute");
use cssSelector for best result.
or else try the following xpath
//div[contains(#class, 'a')]
If you want attribute of div.a with it's descendant span which contains text something, try as below :-
driver.findElement(By.xpath("//div[#class = 'a' and descendant::span[text() = 'Text Example']]")).getAttribute("attribute");
Hope it helps..:)

xpath: how to get the specific text using xpath?

the html is like this:
<div id='id'>
<a href>abc</a>
"xyz"
</div>
I want to use xpath to get the xyz (I use it in capybara), but my xpath can't work
... //div[#id='id'].text
it returns abcxyz
how can I get it?
Text is its own text node, so the correct selector would be:
.//div[#id='id']/text()

can you spot the error in this xpath

I'm a little new to xpath and I was wondering if you anyone can help me understand what's wrong with the following xpath query. The server is telling me I have an "invalid predicate"
Here's the xpath:
xpath("div[span[#class='paragraphnumber]/text()='$next_pn']/#id")
I want this to find the #id of the div which contains within it a span element with the #class of "paragraphnumber" and the text which equals the number contained in the variable $next_pn. The div would look something like this:
<div id="pl8ddjkdj"><span class="paragraphnumber">3</span>lor ipsum etc etc</div>
Basically, I'm starting with the number I want to be able to find the unique id of this div.
Thanks for your help.
You have just missed a single quote (') after the name of the class paragraphnumber.
This:
xpath("div[span[#class='paragraphnumber]/text()='$next_pn']/#id")
should be
// v
xpath("div[span[#class='paragraphnumber']/text()='$next_pn']/#id")

Resources