25

Given that the HTML contains:

  <div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>

How do we write the following expression in XPath:

Find a <div> element whose tagname attribute ends with the string 'Destination'

I've been searching for days and I can't come up with something that works. Among many, I tried for example:

div[contains(@tagname, 'Destination')]
kjhughes
  • 106,133
  • 27
  • 181
  • 240
Happy Bird
  • 1,012
  • 2
  • 11
  • 29

6 Answers6

42

XPath 2.0

//div[ends-with(@tagname, 'Destination')]

XPath 1.0

//div[substring(@tagname, string-length(@tagname) 
                          - string-length('Destination') + 1)  = 'Destination']
kjhughes
  • 106,133
  • 27
  • 181
  • 240
7

XPath 2 or 3: There's always regex.

.//div[matches(@tagname,".*_Destination$")]
Bill Bell
  • 21,021
  • 5
  • 43
  • 58
6

You can use ends-with (Xpath 2.0)

//div[ends-with(@tagname, 'Destination')]
ievche
  • 1,735
  • 14
  • 22
2

You could use the below xpath which will work with Xpath 1.0

//div[string-length(substring-before(@tagname, 'Destination')) >= 0 and string-length(substring-after(@tagname, 'Destination')) = 0 and contains(@tagname, 'Destination')]

Basically it checks if there is any string ( or no strings ) before the first occurrence of Destination but there should not be any text after the Destination

Test input :

<root>
<!--Ends with Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>
<!--just Destination-->
<div tagname="Destination" class="panel panel-default"></div>
<!--Contains Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination_some_text" class="panel panel-default"></div>
<!--Doesn't contain destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276" class="panel panel-default"></div>
</root>

Test output:

<div class="panel panel-default"
     tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination"/>
<div class="panel panel-default" tagname="Destination"/>
SomeDude
  • 13,876
  • 5
  • 21
  • 44
0

Another solution that is XPath 1.0 compatible:

//div[contains(concat(@tagname, 'UNIQUE'), concat('Destination', 'UNIQUE'))]

I used this while searching for entries in a KeePass Database using the XPath expression search feature:

//Entry/String[contains(concat(Key, 'UNIQUE'), '/UNIQUE')]

found all entries that have a custom string field that ends in '/'.

0

Incase you have landed on this discussion for a or based solution, Selenium still supports only where ends-with() isn't supported.


Solution

Given the HTML:

<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>

Using Selenium a potential solution would be to use the contains() method as follows:

//div[contains(@tagname, 'Destination')]

Accomodating the class attributes:

//div[contains(@tagname, 'Destination') and @class='panel panel-default']
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352