XPath to find element based on another XPath element - java

I have an Java AST and I try to find a variable inside it via XPath.
Lets say the variable is called 'foobar' I could use
//VariableDeclarator/VariableDeclaratorId[#Image='foobar']
but what if I dont know the text 'foobar', but want to read it from another element
//VariableDeclarator/VariableDeclaratorId[#Image=//SynchronizedStatement/Expression/PrimaryExpression/PrimaryPrefix/Name]
the 'Name' node has the information 'foobar' in #Image, but PrimaryPrefix/Name[#Image] does not work.
How must I rewrite the condition //SynchronizedStatement/Expression/PrimaryExpression/PrimaryPrefix/Name that it is the same as #Image='foobar' ?
Thanks

Try this XPath:-
//VariableDeclarator/VariableDeclaratorId[#Image=//SynchronizedStatement/Expression/PrimaryExpression/PrimaryPrefix/Name/#Image]

Related

Too many results when finding within element with Selenium WebDriver

I did the following search
parts.get(i).findElements(By.xpath("//li[starts-with(#class, '_lessons--row-')]"))
and it returned dozens of results, while I see in Developer Tools, that there are no more than 3 of them.
parts.get(i) returns single WebElement.
Looks like it searches not children of a given element, but over entire page. Can double slash cause this? What double slash means in XPath?
Your xpath is faulty here.
"//li[starts-with(#class, '_lessons--row-')]"
// searches from root level, to search from node preappend .:
".//li[starts-with(#class, '_lessons--row-')]"
Try your xpath with .// , normally you should start xpath with "." to stop finding elements from root.
.//li[starts-with(#class, '_lessons--row-')]
// match relative data. which starts at the document root. In your case you are trying to locate using
//li[starts-with(#class, '_lessons--row-')]
So it will return all the match in your html. If you want to locate some specific portion of element with class have start text_lessons--row- . You have to make your xpath more specific.
e.g
//div[#id='someid']//li[starts-with(#class, '_lessons--row-')]
I had a similar case, but . before // didn't help me. Just added findElements(By.xpath("your_xpath")).stream().filter(WebElement::isDisplayed).toList() as a workaround.

Why I must search explicitly relative elements in Selenium by xpath?

I'm trying to look for elements by xpath with Selenium's WebDriver:
WebElement element1 = driver.findElement(By.id("someID"));
List<WebElement> xPathElements = element1.findElements((By.xpath("//span[#class='someClass']")));
With this code, I'm getting all the elements with class='someClass' in the DOM.
Only when I add "." at the beginning of the xpath string I get all the elements with class='someClass' that are under element1
element1.findElements((By.xpath(".//span[#class='someClass']")));
What's the sense here? I called findElements from element1 so by default it should search for elements that are under element1, Why I must add the "."?
It has got nothing to do with Selenium, it is the way xpath works.
If you have something like //elem xpath will located anywhere in the document. But if you want to search for an element relative to another element or rather a descendant then you have to use a '.' or a dot like .//elem.
. - select current node
// - Selects nodes in the document from the current node that match the selection no matter where they are. As current node not specified, will search everywhere.
So .// means search everywhere inside current node.
In your case:
//span[#class='someClass'] is //span[#class='someClass']
.//span[#class='someClass'] is element1//span[#class='someClass']
See - xpath syntax

How to getText() for XPath with attribute 'display:none'

I would like to use getText() for one XPath, need text what is there.
//span(contains(#style,'display:none'))
XPath is working tested in firebug, I've tried getText, getAttribute, so far no luck
It's a little hard to say without the exact HTML, which you have not specified in your question...
To begin with, you need to change this:
"//span(contains(#style,'display:none'))"
To this:
"//span[contains(#style,'display:none')]"
UPDATE:
Alternatively, since the span element is not visible, you might be able to do it with:
String innerHTML = elem.getAttribute("innerHTML");
Where elem is the parent node of the span element.
Then, in order to get the actual text, you will need to parse the innerHTML string.
Because the element is invisible (it has display:none), Selenium cannot natively interact with it. You need cast your driver to JavascriptExecutor, then execute the following javascript:
$x("//span(contains(#style,'display:none'))")[0].text
The [0] returns the 1st element returned by the xpath.
This will return the inner text of the element.

How to get Attribute using selector syntax in jsoup

I need to get value of attribute href of a tag.
I know using a.attr("href") I can get href attribute value.
But I want to know is there any other way to get href attribute as like in jTidy
(using syntax like //a/#href) for Jsoup.
Means can I use some selector syntax to get attribute directly ?
Thanks.
No, you cant retrieve the attribute value by a single selector. Its purpose is to select elements by various criteria.
But you can select only those elements which have the attribute and then ask it's value.
Element withAttr = doc.select("a[href]").first();
String attrAvlue = withAttr.attr("href");

Extract attribute's value with XPATH in a special case

hi i need help to extract information from XML with xpath.
I will use Xpath to extract the value of the attribute of one Tag that start with a generic keywork:
<st:Testprova id='abcd'>
....
</st>
or
<st:Test1prova id='defg'>
....
</st>
I used that Xpath expression:
"//*[contains(.,'prova')]/#ID"
but does not work. Can you help me??
You are using #ID instead of #id, this is case sensitive. Besides, you should use name() to retrieve the node-name.
This XPath expression
//*[contains(name(),'prova')]/#id
returns abcd and defg
Although your XML is not correct, it should be:
<st:Testprova id='abcd'>
....
</st:Testprova>
<st:Test1prova id='defg'>
....
</st:Test1prova>
The correct function to be used in this case is matches().
contains() can return true even for node names like
Testprova
Prodprova
UATprova
provaTest
and others which ever contains the word prova.
But if you know the pattern with which the node name will be, then matches() functions filters out exactly the desired nodes.
So if i assume a digit might appear between both the words, the xpath can be written like below
//*[matches(name(), '^Test[0-9]?prova$')]//#ID
Note: matches function is part of Xpath2.0 and will not work in Xpath1.0

Categories