Hi how would I select all link when they have the following id.
<a id="List_ctl01_link3" class="content" href=link1.aspx">
<a id="List_ctl02_link3" class="content" href=link2.aspx">
<a id="List_ctl03_link3" class="content" href=link3.aspx">
<a id="List_ctl04_link3" class="content" href=link4.aspx">
And so on...
Please note that the last part "link3" is important, and must be included in the Xpath.
I'm using C# and Html agility pack.
Hi how would I select all link
when they have the following id
Use this XPath expression:
//a[#id[starts-with(.,'List_ctl')][substring(.,string-length()-5)='_link3']]
Note: There is no fn:ends-with() in XPath 1.0. Use last predicate instead.
Use:
//a[#id[starts-with(.,'List_ctl')
and
substring(.,string-length()-5)='_link3'
and
floor(substring-before(substring_after(.,'List_ctl'),'_'))
=
floor(substring-before(substring_after(.,'List_ctl'),'_'))
]
]
This XPath expression selects all a elements in the document whose id attribute has string value with all of the following properties:
Starts with the string 'List_ctl' .
Ends with the string '_link3' .
The substring surrounded by 'List_ctl' and '_' is a representation of an integer.
In case you use xpath 2.0 you can try match/matches functions and use regular expressions. If you are with xpath 1.0 probably you will have to write your custom attribute parser (take a look at xsl:function). AFAIR the match function is available only xpath 2.0.
Probably #id[starts-with(., 'List_ct') and ends-with(., 'link3')] is another way to do it.
Related
I want to write a common XPath for the result displayed for my searched text 'Automation Server'
The same text is displayed for td HTML tags as well as for div html tags as shown below, and I wrote XPath as below based on my understanding by going through different article
displayed_text = //td[contains(text(),'Automation Server') or div[contains(text(),' Automation Server ')]
<td role="cell" mat-cell="" class="mat-cell cdk-cell cdk-column-siteName mat-column-siteName ng-star-inserted">Automation Server</td>
<div class="change-list-value ng-star-inserted"> Automation Server </div>
The operator you are looking for in XPath is |. It is a union operator and will return both sets of elements.
The XPath you are looking for is
//td[contains(text(),'Automation Server')] | //div[contains(text(),'Automation Server')]
This XPath,
//*[self::td or self::div][text()[normalize-space()='Automation Server']]
will select all td or div elements with an immediate text node whose normalize string value equals 'Automation Server'.
Cautions regarding other answers here
| is not logical-OR or "OR-like".
It is a union operator over node sets (XPath 1.0) or sequences (XPath 2.0+), not boolean values.
See: Logical OR in XPath? Why isn't | working?
contains(text(), "string") only tests the first text node child.
See: Why is contains(text(), "string" ) not working in XPath?
A few alternatives to JeffC answer, using common properties for both:
1. use the * as a wildcard for any element:
//*[contains(#class,'ng-star-inserted') and normalize-space(text())='Automation Server']
2. use in addition the local-name() function to narrow down the names of the elements:
//*[local-name()[.='td' or .='div']][contains(#class,'ng-star-inserted') and normalize-space(text())='Automation Server']
The normalize-space() function can be used to clean-up the optional white space, so a = operator can be used.
You could use the following XPath to test the local-name() of the element in a predicate and whether it's text() contains the phrase:
//*[(local-name() = "td" or local-name() = "div") and contains(text(), "Automation Server")]
I have a website I need to isolate XPATH identifiers on - they have an XPath ID like this //*[#id="panel-detail-6163748c7952a-partnerCode"]
The issue is that the website changes the value 6163748c7952a on every page load.
Is there any such XPath expression which can match on the first/last part of that string? So of a wildcard like //*[#id="panel-detail-*-partnerCode"]
This XPath 2.0 expression,
//*[matches(#id, "^panel-detail-.*-partnerCode$")]
or this XPath 1.0 expression,
//*[starts-with(#id, 'panel-detail-') and
substring(#id, string-length(#id) - string-length('-partnerCode') + 1)
= '-partnerCode']
will match all elements whose id attribute value starts and ends with the noted substrings.
See also
XPath testing that string ends with substring?
There are few methods in xpath such as starts-with or ends-with. Many time folks replaces them with contains which should be discourage.
Please note that ends-with is available with xpath v2.0 .
xpath v1.0 :
//*[starts-with(#id,'panel-detail-') and contains(#id, '-partnerCode')]
xpath v2.0 :
//*[starts-with(#id,'panel-detail-') and ends-with(#id, '-partnerCode')]
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.
I need to get the count of <a> tag which is inside <span> and not anywhere else. I'm using robot framework selenium2library and I cannot use absolute xpath. It has to be relative.
I tried to create nested xpath without any attributes but it's not allowed.
<a class="xyz"></a>
<span>
<a class="xyz"></a>
<a class="xyz"></a>
</span>
${count}= Get Element Count xpath=//span[]//a[contains(#class, 'xyz')]
I expect ${count} to be ${2}, but the error is
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//span[]//a[contains(#class, 'xyz']' is not a valid XPath expression
You expression incorrect.
You don't need []
You need ), change you xpath like this :
//span//a[contains(#class, 'xyz')]
As #frianH pointed, your Xpath expression is wrong, if you want to use class name for match count then you should use use //span//a[#class='xyz'], as 'contains' could be brittle here since you are matching by text.
Now one can argue that //span//a[#class, 'xyz'] is better way to use it but in your case earlier is better approach.
there can be other better way, you need to do some research and see what best fits in your case.
For example if I have multiple anchor elements on a site and the easiest way to get them is via their ID, but the IDs look like this:
lots of html...
hop1
...lots of html...
hop2
...lots of html...
hop3
...lots of html
Is it possible to select the href attributes of all anchor elements whose id has the "foo_" part of the id? In other words, can I add a wildcard in an attribute's value in XPath?
This XPath expression, which works with all versions of XPath,
//a[starts-with(#id,"foo_")]/#href
will select all a/#href attributes whose a has an id attribute value that starts with "foo_".
Yes you can use matches function in terms of XSL:
Starting with foo_ //a/#id[matches(.,'^foo_\d+')]
Containing foo_ //a/#id[matches(.,'foo_\d+')]
Please specify for which language you are asking for