Can I get value of an specific attribute only by XPath? - ruby

I have a code like this:
doc = Nokogiri::HTML("<a href='foo.html'>foo</a><a href='bar.html'>bar</a>")
doc.xpath('//a/#href').map(&:value) # => ["foo.html", "bar.html"]
It works as I expected.
But just out of curiosity I want to know, can I also get the value of href attributes only by using XPath?

Locate attributes first
example:
site name:
https://www.easymobilerecharge.com/
We want to locate "MTS" link
In your case, to locate this element, we can use x-path like:
//a[contains(text(),'MTS')]
Now to get href attribute, use:
//a[contains(text(),'MTS')]/#href

Judging from the first answer to this question the answer seems to be yes and no. It offers
xml.xpath("//Placement").attr("messageId")
which is quite close to "only XPath", but not entirely. Up to you to judge if that is enough for you.

Related

Xpath combine two #class elements

I want to find the following element on a web site: //a[#class="a-link-normal"]/#href
inside this element: //div[#class="s-result-list s-search-results sg-row"].
I tried this one:
//*[contains(#class='s-result-list s-search-results sg-row') and contains(#class='a-link-normal')]"))
but it doesn't work, xpath helper shows "invalid xpath expression".
Probably the solution is quite simple, but i can't make it work.
Thanks in advance
So, Amazon. You're looking for this (you didn't use the correct div) :
//div[#class="s-main-slot s-result-list s-search-results sg-row"]//a[#class="a-link-normal"]

Is it possible to use Following and preceding in combination in Selenium?

On this page
https://en.wikipedia.org/wiki/Trinity_Seven#Episode_list
I have:
//*[text()='Reception']//preceding::th[contains(#id, 'ep')]//following::I
But it only registers following.
The default firepath selector is: .//*[#id='mw-content-text']/div/table[5]/tbody/tr/td[1]/I but this kind of selector is known to break quite frequently. Just wondering if there is a better way of doing this and I thought this might be a way.
Thanks!
:)
- You can see that it's getting stuff under the table which is not what I want :S
Try to use below XPath to match required elements:
//th[contains(#id, 'ep')]/following::I[./following::*[text()='Reception']]
This looks more simple
//tr[contains(#class, 'vevent')]//i
Don't overcomplicate things. You need I tag inside each row. So just find row locator tr[contains(#class, 'vevent')] and get it's I
Another good approach in case you want to check that inside of parent element is located some special element, but you want to find some 3rd element is to use such style: //element[./specific]//child , so in your case:
//tr[contains(#class, 'vevent')][./th[contains(#id,'ep')]]//i
so it's I tag inside row that contains #id,'ep' in header

How to use substring() with Import.io?

I'm having some issues with XPath and import.io and I hope you'll be able to help me. :)
The html code:
<a href="page.php?var=12345">
For the moment, I manage to extract the content of the href ( page.php?var=12345 ) with this:
./td[3]/a[1]/#href
Though, I would like to just collect: 12345
substring might be the solution but it does not seem to work on import.io as I use it...
substring(./td[3]/a[1]/#href,13)
Any ideas of what the problem is?
Thank's a lot in advance!
Try using this for the xpath: (Have the field selected as Text)
.//*[#class='oeil']/a/#href
Then use this for your regex:
([^=]*)$
This will get you the ISBN number you are looking for.
import.io only support functions in XPath when they return a node list
Your path expression is fine, but perhaps it should be
substring(./td[3]/a[1]/#href,14)
"Does not seem to work" is not a very clear description of what is wrong. Do you get error messages? Is the output wrong? Do you have any code surrounding the path expression you could show?
You can use substring, but using substring-after() would be even better.
substring-after(/a/#href,'=')
assuming as input the tiny snippet you have shown:
<a href="page.php?var=12345"/>
will select
12345
and taking into account the structure of your input
substring-after(./td[3]/a[1]/#href,'=')
A leading . in a path expression selects only immediate child td nodes of the current context node. I trust you know what you are doing.

Get the value of title using xPath

I am using the following but it does not get me the value of the title
//*[#id="843285"]/td[3]/a[#title]
Elche vs Osasuna
Can someone give me some guidance?
Few ways to find you the element directly, then use #title to get the title attribute. Note that your id is g843285, not 843285.
If it's always <a> tag (otherwiser use * but with lower performance)
//a[#id="g843285"]/#title
//a[contains(#id, "843285")]/#title
//a[contains(#href, "match/843285")]/#title
I assume you don't know the match teams (otherwise you won't need to find out title), so the following won't work, posting here just for references.
//a[text() = 'Elche vs Osasuna']/#title
"Find the element whose ID attribute equals "843285", and return the value of its title attribute"
//*[#id="843285"]/#title
You can do this if you're always dealing with a tags
//a[#id="g843285"]/#title
Otherwise do //*[#id="g843285"]/#title

using xpath in selenium.get.Text and selenium.click

I have Адреса магазинов on page and want to store text, then click on this link and verify that the page where am I going to contains this text in headers. So I tried to find element by xpath, and selenium.getText get the right result, but selenium.click goes to another link. Where have I made a mistake? Thanks in advance!
String m_1 = selenium.getText("xpath=html/body/div[3]/div[2]/div[1]/h4[1]");
selenium.click("xpath=html/body/div[3]/div[2]/div[1]/h4[1]");
selenium.waitForPageToLoad("30000");
assertTrue(selenium.getText("css=h3").contains(m_1));
page:http://www.svyaznoy.ru/map/
Resume:
using xpath=//descendant::a[#href='/address_shops/'][2] or css=div.deff_one_column a[href='/address_shops/'] get right results
using xpath=//a[#href='/address_shops/'] - Element is not currently visible
xpath=//a[#href='/address_shops/'][2] - Element not found
There is a missing slash at the beginning of the expression. I am kind of surprised this got through at all - the first slash means "begin at root node".
Also, it is better to select the <a> element instead of the <h>. Sometimes it works, sometimes is misclicks, sometimes the click doesn't do anything at all. Try to be as concrete as you can be.
Try this one.
String m1 = selenium.getText("xpath=/html/body/div[3]/div[2]/div/h4/a");
selenium.click("xpath=/html/body/div[3]/div[2]/div/h4/a");
selenium.waitForPageToLoad("30000");
// your variable is named m1, but m_1 was used here
assertTrue(selenium.getText("css=h3").contains(m1));
By the way, there are even better XPath expressions you could use. See the documentation, it really is helpful. Just an example, this would work, too, and is much easier to write and read:
String m1 = selenium.getText("xpath=//a[#href='/address_shops/']");
selenium.click("xpath=//a[#href='/address_shops/']");
Sorry, didn't notice page link. Css for second link can be something like that css=div.deff_one_column a[href='/address_shops/']

Resources