case-insensitive matching in XPath?

127,170

Solution 1

XPath 2 has a lower-case (and upper-case) string function. That's not quite the same as case-insensitive, but hopefully it will be close enough:

//CD[lower-case(@title)='empire burlesque']

If you are using XPath 1, there is a hack using translate.

Solution 2

matches() is an XPATH 2.0 function that allows for case-insensitive regex matching.

One of the flags is i for case-insensitive matching.

The following XPATH using the matches() function with the case-insensitive flag:

//CD[matches(@title,'empire burlesque','i')]

Solution 3

This does not work in Chrome Developer tools to locate a element, i am looking to locate the 'Submit' button in the screen

//input[matches(@value,'submit','i')]

However, using 'translate' to replace all caps to small works as below

//input[translate(@value,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'submit']

Update: I just found the reason why 'matches' doesnt work. I am using Chrome with xpath 1.0 which wont understand the syntax 'matches'. It should be xpath 2.0

Solution 4

One possible PHP solution:

// load XML to SimpleXML
$x = simplexml_load_string($xmlstr);

// index it by title once
$index = array();
foreach ($x->CD as &$cd) {
  $title = strtolower((string)$cd['title']); 
  if (!array_key_exists($title, $index)) $index[$title] = array();
  $index[$title][] = &$cd;
}

// query the index 
$result = $index[strtolower("EMPIRE BURLESQUE")];

Solution 5

for selenium xpath lower-case will not work ... Translate will help Case 1 :

  1. using Attribute //*[translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='login_field']
  2. Using any attribute //[translate(@,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='login_field']

Case 2 : (with contains) //[contains(translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'login_field')]

case 3 : for Text property //*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'username')]

Share:
127,170

Related videos on Youtube

Ethan
Author by

Ethan

SOreadytohelp

Updated on September 05, 2021

Comments

  • Ethan
    Ethan almost 3 years

    For example, for the XML below

    <CATALOG>
        <CD title="Empire Burlesque"/>
        <CD title="empire burlesque"/>
        <CD title="EMPIRE BURLESQUE"/>
        <CD title="EmPiRe BuRLeSQuE"/>
        <CD title="Others"/>
    <CATALOG>
    

    How to match the first 4 records with xpath like //CD[@title='empire burlesque']. Is there xpath function to do this? Other solutions like PHP function are also accepted.

  • Tomalak
    Tomalak almost 13 years
    To the anonymous down-voter: Read the OP's question. Especially the "Other solutions like PHP function are also accepted." part.
  • usr
    usr over 10 years
    This is regex-based which is an important difference to text-based matching.
  • T.J. Crowder
    T.J. Crowder almost 9 years
    Even works in SQL Server's XPath queries on XML columns. Excellent.
  • neaumusic
    neaumusic over 4 years
    It seems the translate concept is called 'case insensitive collation' in regards to internationalization
  • Stephan
    Stephan over 3 years
    Also bear in mind that the translate solution in this answer won't work for languages (german for instance) having special rules for uppercase letters.
  • Arjan
    Arjan about 3 years
    Beware that this may also find partial matches; if that's not acceptable then use ^ and $, like matches(@title, '^empire burlesque$', 'i')
  • Kamil
    Kamil over 2 years
    You helped me a lot. Many thanks!