Extract class attribute using xpath - html

I have the following html:
<div class="g-recaptcha" data-sitekey="6LdWKrUUAAAAAP3b4V05YVzvFNJNAUrDb0RoJZf7" data-callback="reValidateP" data-expired-callback="reInvalidateP" style="clear:left;">
How can I extract sitekey value attribute via Xpath?

XPath 1.0 solution :
string(//div[#class="g-recaptcha"]/#data-sitekey)
Output : 6LdWKrUUAAAAAP3b4V05YVzvFNJNAUrDb0RoJZf7

Related

Why is contains(text(), "string" ) not working in XPath?

I have written this expression //*[contains(text(), "Brand:" )] for the below HTML code.
<div class="info-product mt-3">
<h3>Informazioni prodotto</h3>
Brand: <span class="brand_title font-weight-bold text-uppercase">Ava</span><br> SKU: 8002910009960<br> Peso Lordo: 0.471 kg <br> Dimensioni: 44.00 × 145.00 × 153.00 mm<br>
<p class="mt-2">
AVA BUCATO A MANO E2 GR.380</p>
</div>
The xpath that I have written is not working I want to select Node that contains text Brand:. Can someone tell me my mistake?
Your XPath,
//*[contains(text(), "Brand:")]
in XPath 1.0 will select all elements whose first text node child contains a "Brand:" substring. In XPath 2.0 it is an error to call contains() with a sequence of more than one item as the first argument.
This XPath,
//*[text()[contains(., "Brand:")]]
will select all elements with a text node child whose string value contains a "Brand:" substring.
See also
XPath 1.0 vs 2.0+ different contains() behavior explanation
Testing text() nodes vs string values in XPath

XPath testing that string ends with substring?

Given that the HTML contains:
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>
How do we write the following expression in XPath:
Find a <div> element whose tagname attribute ends with the string 'Destination'
I've been searching for days and I can't come up with something that works. Among many, I tried for example:
div[contains(#tagname, 'Destination')]
XPath 2.0
//div[ends-with(#tagname, 'Destination')]
XPath 1.0
//div[substring(#tagname, string-length(#tagname)
- string-length('Destination') + 1) = 'Destination']
You can use ends-with (Xpath 2.0)
//div[ends-with(#tagname, 'Destination')]
XPath 2 or 3: There's always regex.
.//div[matches(#tagname,".*_Destination$")]
You could use the below xpath which will work with Xpath 1.0
//div[string-length(substring-before(#tagname, 'Destination')) >= 0 and string-length(substring-after(#tagname, 'Destination')) = 0 and contains(#tagname, 'Destination')]
Basically it checks if there is any string ( or no strings ) before the first occurrence of Destination but there should not be any text after the Destination
Test input :
<root>
<!--Ends with Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>
<!--just Destination-->
<div tagname="Destination" class="panel panel-default"></div>
<!--Contains Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination_some_text" class="panel panel-default"></div>
<!--Doesn't contain destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276" class="panel panel-default"></div>
</root>
Test output:
<div class="panel panel-default"
tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination"/>
<div class="panel panel-default" tagname="Destination"/>
Another solution that is XPath 1.0 compatible:
//div[contains(concat(#tagname, 'UNIQUE'), concat('Destination', 'UNIQUE'))]
I used this while searching for entries in a KeePass Database using the XPath expression search feature:
//Entry/String[contains(concat(Key, 'UNIQUE'), '/UNIQUE')]
found all entries that have a custom string field that ends in '/'.

Get div class title content text using xpath

I have a requirement of getting the text below of "ELECTRONIC ARTS" (this can change according to data) using class title "Offered By" (this class will be same for all) using Xpath. I tried various xpath coding, but couldn't get the results I want. I'm really looking for someone's help on this.
<div class="meta-info">
<div class="title"> Offered By</div>
<div class="content">ELECTRONIC ARTS</div> </div>
This is one possible XPath expression to starts with, which then you can simplify or add more criteria as needed (XPath formatted to be more readable) :
//div[
#class='meta-info'
and
div[#class='title' and normalize-space()='Offered By']
]/div[#class='content']
explanation :
//div[#class='meta-info' and ... : find div element where class attribute value equals "meta-info" and ...
div[#class='title' and normalize-space()='Offered By']] : ... has child element div where class attribute value equals "title" and content equals "Offered By"
/div[#class='content'] : from such div (the <div class="meta-info"> to be clear), return child element div where class attribute value equals "content"
Using the examples on Mozilla:
var xpath = document.evaluate("//div[#class='content']", document, null, XPathResult.STRING_TYPE, null);
document.write('The text found is: "' + xpath.stringValue + '".');
console.log(xpath);
<div class="meta-info">
<div class="title"> Offered By</div>
<div class="content">ELECTRONIC ARTS</div>
</div>
By the way, I think document.querySelector or document.querySelectorAll are much more convenient in this situation:
var content = document.querySelector('.meta-info .content').innerText;
document.write('The text found is: "' + content + '".');
console.log(content);
<div class="meta-info">
<div class="title"> Offered By</div>
<div class="content">ELECTRONIC ARTS</div>
</div>

How can I get list of elements or data which are on same level with same attributes?

I have one web application which have one HTML page.
In this page structure is like this:
<div class = 'abc'>
<div class = 'pqr'>test1</div>
</div>
<div class = 'abc'>
<div class = 'pqr'>-</div>
</div>
<div class = 'abc'>
<div class = 'pqr'>-</div>
</div>
<div class = 'abc'>
<div class = 'pqr'>test2</div>
</div>
<div class = 'abc'>
<div class = 'pqr'>-</div>
</div>
Here I want to take data from test1 to test2.
I have tried xpath with [Node Number] But I have found all nodes at [1] level.
Is there any way to get all data or List of elements test1 to test2 with "-" ?
I have seen this kind of issue before.
You have to use following-sibling here.
First I use this type of xpath :
//div[text()='test1']/..//following-sibling::div[#class='pqr' and not(contains(text(),'test'))]
Then you need to change script. "Note : I have written code in JAVA"
Logic :
while(element found text = '-')
{
//get data here
}
Please try this approach.
I guess you want the following xpath :
(//div[#class='pqr'])[position()<=4]
Notice the brackets () before position() predicate.
output in xpath tester :
Element='<div class="pqr">test1</div>'
Element='<div class="pqr">-</div>'
Element='<div class="pqr">-</div>'
Element='<div class="pqr">test2</div>'
I think you can't use the Test1 and Test2 elements as identifiers because they are on the same line as the nodes you want to collect. Otherwise, I think you can use findElements(by.Xpath("patern_to_search")). that will return you a collection of elements that are matching your pattern.
one more way without using xpath:
List<WebElement> element = driver.findElements(By.className("pqr"));
for(int i=0;i<element.size()-1;i++){
System.out.println(element.get(i).getText());
}

Extract URL using xpath

What xpath should i use to extract the "URL" and title="TEXT" from this html code:
<div class="VersionAnglaise"> <a href="URL" title="Version Anglaise"
class="LienVersionAnglaise"><strong>Version anglaise</strong></a> </div>
Thanks in advance.
To get title attribute :
//div[#class='VersionAnglaise']/a/#title
To get href attribute :
//div[#class='VersionAnglaise']/a/#href
You can combine both using XPath union (|) :
//div[#class='VersionAnglaise']/a/#title | //div[#class='VersionAnglaise']/a/#href