Xpath: Get Text After Element With Containing Text - html

I am looking for a way to get text which is not inside an HTML element:
<div class="col-sm-4">
<strong>Handelnde Personen:</strong><br><br>
<strong>Geschäftsführer</strong><br>
Mr John Doe<br>
Privatperson<br>
.....<br>
<br>
I want to get "Mr John Doe".
The only way I see is looking for a strong element which contains "Geschäftsführer" and then look for the following text.
My idea so far:
//strong[contains(text(), 'Gesch')]/br/../text()
... I simply can't make it work.
Also, is there a "wildcard" for strings? That I could use
*esch*ftsf*hr*
for "Geschäftsführer"?
I highly appreciate your help, thanks!

Try
//strong[starts-with(., 'Gesch')]/following-sibling::text()[1]
As for wildcard matching, with XPath 2.0 you use regular expressions:
//strong[matches(., '.*esch.*ftsf.*hr.*')]
With XPath 3.0 you could also use the Unicode collation algorithm
//strong[compare(., 'Geschäftsführer',
'http://www.w3.org/2013/collation/UCA?strength=primary') = 0]
(strength=primary ignores case and accents)
But to get anything more advanced than XPath 1.0 in the browser, you would need to deploy Saxon-JS.
Another option with 1.0 is to use translate() to remove case and umlauts:
//strong[translate(., 'ABCD..XYZÄÖÜäöüß', 'abcd..xyzaouaous') = 'geschaftsfuhrer']
Note, in all these examples I have used "." rather than "text()" to get the string value of an element - this is recommended practice.

Related

Find XPath of Text which is Under Div Tag and besides span tag

Sorry if this is discussed before. I tried searching it but didn't find exact match. My question is I have low HTML code,
<div class="column1">
<div>
<div class="name">
Dynamic Name
<span class="id" title="ID">Dynamic ID</span>
</div>
</div>
</div>
I am looking for XPath to get text Dynamic Name.
Here is what I tried which didn't work
1. //div/div[#class='name'] which is finding text Dynamic Name Dynamic ID
2. //div/span[#class='id']/preceding-sibling::text()
Since Dynamic Name & Dynamic ID, both are the dynamic value, I can't use split & use name as we don't know where to split it.
Thanks in advance for your time & help.
This XPath,
normalize-space(//div[#class="name"]/text())
will return "Dynamic Name" for your HTML, as requested.
Thanks but it has some syntax error as i tried putting on Firepath and its giving some error. not sure which one.
Wild guess: See if
//div[#class="name"]/text()
avoids your syntax error (which would be a limitation of your tool as normalize-space() is a proper XPath 1.0 function) and selects your targeted text (although with extraneous whitespace).
Since you stated that the XPath //div/div[#class='name'] is working but returns too much info, we can grab that element, grab the innerHTML, and then split on the first <, take the first String, and trim() it just in case to get the answer.
driver.findElement(By.xpath("//div/div[#class='name']")).getAttribute("innerHTML").split("<")[0].trim();

unable to get xpath of anchor element under span element

I have already learned to use xpath but i am kind of stuck here - http://phptravels.com/requirements/. Can anyone please tell me how to find xpath of "Demo" hyperlink on this website. I simply used //a[text()= 'Demo ']. keep whitespaces in mind.
Try to bind the xpath with an id which is persistent, you can consider using this xpath:
//nav[#id='main-menu']/ul/li/span/span/a[contains(text(), 'Demo')]
The white space is your problem. Use contains instead of equality
//a[contains(text(), 'Demo')]
Or
//a[contains(., 'Demo')]
Here with equals, but better to use contains (or starts-with), as described #Guy
driver.findElement(By.xpath("//a[text()='Demo\n ']")).getText();
to get real text value of element - you can use this:
driver.findElement(webElement).getAttribute("text")

is it possible to read the text of a li using Xpath with different attributes?

I am aware that I can directly use:
driver.FindElement(By.XPath("//ul[3]/li/ul/li[7]")).Text
to get the text .. but I am trying get the text by using Xpath and combination of different attributes like text(), contains() etc.
//ul[3]/li/ul/li//[text()='My Data']
Please suggest me different ways that I can handle this ... except the one I mentioned.
<li class="ng-binding ng-scope selectedTreeElement" ng-click="orgSelCtrl.selectUserSessionOrg(child);" ng-class="{selectedTreeElement: child.organizationId == orgSelCtrl.SelectedOrg.organizationId}" ng-repeat="child in node.childOrgs" style="background-color: transparent;"> My Data </li>
looks like you have extra "/" in your xpath and you miss dot:
//ul[3]/li/ul/li//[text()='My Data']
try this:
.//ul[3]/li/ul/li[text()='My Data']
BUT you are use xpath only for find elements, but not for reading its attributes. If you need to read attribute or text inside of it, you need to use selenium after search.
.Text of a WebElement would just return you the text of an element.
If you want to make expectations about the text, check the text() inside the XPath expression, e.g.:
//ul[3]/li/ul/li[text()='My Data']
or, using contains():
//ul[3]/li/ul/li[contains(text(), 'My Data')]
There are other functions you can make use of, see Functions - XPath.
You can also combine it with other conditions. For instance:
//ul[3]/li/ul/li[contains(#class, 'selectedTreeElement') and contains(text(), 'My Data')]

RegEx to substitute tag names, leaving the content and attributes intact

I would like to replace opening and closing tag, leaving the content of tags and its attribute intact.
Here is what I have:
<div class="QText">Text to be kept</div>
to be replaced with
<span class="QText">Text to be kept</span>
I tried this expression which finds all expressions I want but there seems to be no way to replace found expressions.
<div class="QText">(.*?)</div>
Thanks in advance.
I think #AmitJoki's answer will work well enough in certain circumstances, but if you only want to replace div elements when they have an attribute or a specific set of attributes, then you would want to use a regex replacement with backreferences - how you specify and refer to a backreference, unfortunately, depends upon your chosen editor. Visual Studio has the most unique and annoying "flavor" of regex I know of, while Dreamweaver has a fairly typical implementation (both as well as I imagine whatever editor you're using do regex replacement - you just have to know the menu item or keystroke to bring up the dialog).
If memory serves, Dreamweaver has replacement options when you hit Ctrl+F, while you have to hit Ctrl+H, so try those.
Once you get a "Find" and "Replace" box, you would put something like what you have in your last example above: <div class="QText">(.*?)</div> or perhaps <div class="(QText|RText|SText)">(.*?)</div> into your "Find" box, then put something like <span class="QText">\1</span> or <span class="\1">\2</span> in the "Replacement" box. A few utilities might use $1 to refer to a backreference rather than \1, but you'll have to lookup help or experiment to be sure.
If you are using a language to run this expression, you need to tell us which language.
If you are using a specific editor to run this expression, you need to tell us which editor.
...and never forget the prevailing wisdom on regex and HTML
Just replace div.
var s="<div class='QText'>Text to be kept</div>";
alert(s.replace(/div/g,"span"));
Demo: http://jsfiddle.net/9sgvP/
Mark it as answer if it helps ;)
Posted as requested
If its going to be literal like that, capture what's to be kept, then replace the rest,
Find: <div( class="QText">.*?</)div>
Replace: <span$1span>

Selenium: test if element contains some text

With Selenium IDE, how can I test if an element's inner text contains a specific string? For example:
<p id="fred">abcde</p>
'id=fred' contains "bcd" = true)
The Selenium-IDE documentation is helpful in this situation.
The command you are looking for is assertText, the locator would be id=fred and the text for example *bcd*.
It can be done with a simple wildcard:
verifyText
id="fred"
*bcd*
See selenium IDE Doc
You can also use:
assertElementPresent
css=p#fred:contains('bcd')
A solution with XPath:
Command: verify element present
Target: xpath=//div[#id='fred' and contains(.,'bcd')]
Are you able to use jQuery if so try something like
$("p#fred:contains('bcd')").css("text-decoration", "underline");
It seems regular expressions might work:
"The simplest character set is a character. The regular expression "the" contains three
character sets: "t," "h" and "e". It will match any line with the string "the" inside it.
This would also match the word "other". "
(From site: http://www.grymoire.com/Unix/Regular.html)
If you are using visual studio there is functionality for evaluating strings with regular expressions of ALL kinds (not just contains):
using System.Text.RegularExpressions;
Regex.IsMatch("YourInnerText", #"^[a-zA-Z]+$");
The expression I posted will check if the string contains ONLY letters.
Your regular expression would then according to my link be "bcd" or some string you construct at runtime. Or:
Regex.IsMatch("YourInnerText", #"bcd");
(Something like that anyway)
Hope it helped.
You can use the command assertTextPresent or verifyText