Xpath insert "," after every li - xpath

I have a piece of code and XPath to export it. the code is:
<div class="container-fluid">
<ul class="tags expandable">
<li><a class="search__link" href="domain.com">office</a></li>
<li><a class="search__link" href="domain.com">space</a></li>
</ul>
</div>
and the Xpath is :
//ul[contains(concat (" ", normalize-space(#class), " "), " tags expandable ")]
this Xpath export data is like this: "office space"
but I want to insert "," after each li and I want the export like this: "office, space,"

You should use something like this with XPath 1.0:
translate(normalize-space(//ul)," ",",")
returns "office,space".
To add the last coma :
concat(translate(normalize-space(//ul)," ",","),",")
returns "office,space,".
EDIT : With the website link you posted, use this one-liner to get what you want :
translate(normalize-space(//div[#class="container-fluid"]/ul)," ",",")
Output :
People,Space,Women,Friends,Communication,Group,Support,Community,Beautiful,Unity,Gender,Movement,Gathering,Copy,Rights,Feminist,Empower,Supporting,Copy,space,Empowering
It still needs some corrections (remove the undesired "," between Copy and space). If you need something fully automatic and since you have to use XPath 1.0 (no replace function), you can try :
translate(normalize-space(translate(//div[#class="container-fluid"]/ul," ",""))," ",",")
Output (Copy space are now merged) :
People,Space,Women,Friends,Communication,Group,Support,Community,Beautiful,Unity,Gender,Movement,Gathering,Copy,Rights,Feminist,Empower,Supporting,Copyspace,Empowering
Otherwise, just use :
//ul[#class="tags expandable"]//a/text()
And add the comas with the programming language you want.

Related

How to use anchor link or HTML in ternary operator in thymeleaf

I encountered a problem that need to write some HTML codes in ternary operator in Thymeleaf. In where I need to chose an anchor link by using ternary operator. For better understand, I putted those problematic code in below:
<span th:text="${error_code == '404'} ? 'Home' : 'Login'"></span>
So, how can I wirte those code correclty in Themeleaf
This should do it :
<span th:utext="((${error_code} == '404') ? '<a href="http://localhost:8080/home">Home</a>' : '<a href="http://localhost:8080/login">Login</a>')"></span>
" is for escaping double quote in html.
utext is to tell thymeleaf not to print plain text as "< a href.. "

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 in RSelenium for indexing list of values

Here is an example of html:
<li class="index i1"
<ol id="rem">
<div class="bare">
<h3>
<a class="tlt mhead" href="https://www.myexample.com">
<li class="index i2"
<ol id="rem">
<div class="bare">
<h3>
<a class="tlt mhead" href="https://www.myexample2.com">
I would like to take the value of every href in a element. What makes the list is the class in the first li in which class' name change i1, i2.
So I have a counter and change it when I go to take the value.
i <- 1
stablestr <- "index "
myVal <- paste(stablestr , i, sep="")
so even if try just to access the general lib with myVal index using this
profile<-remDr$findElement(using = 'xpath', "//*/input[#li = myVal]")
profile$highlightElement()
or the href using this
profile<-remDr$findElement(using = 'xpath', "/li[#class=myVal]/ol[#id='rem']/div[#id='bare']/h3/a[#class='tlt']")
profile$highlightElement()
Is there anything wrong with xpath?
Your HTML structure is invalid. Your <li> tags are not closed properly, and it seems you are confusing <ol> with <li>. But for the sake of the question, I assume the structure is as you write, with properly closed <li> tags.
Then, constructing myVal is not right. It will yield "index 1" while you want "index i1". Use "index i" for stablestr.
Now for the XPath:
//*/input[#li = myVal]
This is obviously wrong since there is no input in your XML. Also, you didn't prefix the variable with $. And finally, the * seems to be unnecessary. Try this:
//li[#class = $myVal]
In your second XPath, there are also some errors:
/li[#class=myVal]/ol[#id='rem']/div[#id='bare']/h3/a[#class='tlt']
^ ^ ^
missing $ should be #class is actually 'tlt mhead'
The first two issues are easy to fix. The third one is not. You could use contains(#class, 'tlt'), but that would also match if the class is, e.g., tltt, which is probably not what you want. Anyway, it might suffice for your use-case. Fixed XPath:
/li[#class=$myVal]/ol[#id='rem']/div[#class='bare']/h3/a[contains(#class, 'tlt')]

Use xpath or xquery to show text in title attribute

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>

XPath Expressions - find elements without specifying the entire path

I am doing some screen scraping with a library that takes XPath expressions and noticed that several pages are similar, but different.
Is there a way to loosely say "get me divs that have class='mytarget' but exist as a child of a div with class = 'nav' and the exact path is unknown between nav and mytarget."
<div class="nav">
<div>
??????
<div class="mytarget"></div>
??????
</div>
</div>
Yes, using the descendant-or-self axis (//):
//div[#class='nav']//div[#class='mytarget']
Or, if there can be more than one class name on those elements, then this is even better:
//div[contains(concat(' ', #class, ' '), ' nav ')]//
div[contains(concat(' ', #class, ' '), ' mytarget ')]
Warning: this can be very inefficient on large documents. You should use absolute paths wherever the structure is known. Only resort to // when the structure is unknown.
Thats what "//" expressions are for. Something like:
//*[#class="nav"]//*[#class="mytarget"]
http://www.w3schools.com/xpath/xpath_syntax.asp

Resources