Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i make Xpath search case insensitive

Tags:

php

xml

xpath

I'm currently making a xpath search, I've got the the search working but I need to make it case insensitive. The xml file I'm using is 1.0 which from my research means I've got to use some thing called a translate function but I'm unsure of how to do this.

Here is my search file :

$holidayDoc = simplexml_load_file('holidays.xml');      

// fetch data from form
$txtSearch = $_GET['txtSearch'];

$qry = "//channel/item[contains(.,\"$txtSearch\")]";


$holidays = $holidayDoc->xpath($qry);   // do the xpath query 
// now loop through all the students

echo "Showing title search results for $txtSearch";

foreach ($holidays as $holiday) 
{

 echo "<p><a href=\"{$holiday->link}\">{$holiday->title}</a></p>
    <p><small>$holiday->pubDate</small></p>";

Any help would be greatly appreciated thanks.

like image 272
user1302775 Avatar asked Apr 22 '12 07:04

user1302775


3 Answers

A case insensitive search can be using using the matches function like so

$qry = "//string[text() [matches(.,'^stringImTryingToFind$','i')]]"

the //string[text() [matches(.,'^OK$','i')]] section of the query uses regular expressions (REGEX) to determine a match.

like image 157
swift nub Avatar answered Oct 04 '22 04:10

swift nub


XPath 1.0 :

$qry = "//channel/item[contains(
 translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),  
 translate($search, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))]"

XPath 2.0 :

$qry = "//channel/item[lower-case(.) = lower-case($search)]"

Both replace all upper case to lower case.

like image 18
alain.janinm Avatar answered Oct 20 '22 18:10

alain.janinm


The currently accepted answer is flawed -- because nothing guarantees that the second argument of contains() is already converted to lower case.

Also, it uses '$search' -- and this is literally the string "$search" -- not the variable $search.

Here is a correct solution:

//channel/item
   [contains(translate(., 
                       'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 
                       'abcdefghjiklmnopqrstuvwxyz'),
             translate($txtSearch, 
                       'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 
                       'abcdefghjiklmnopqrstuvwxyz')
             )
   ]

The corresponding XPath 2.0 expression:

//channel/item[contains(lower-case(.), lower-case($txtSearch))]

Update:

Based on this solution, @alain.janinm has corrected his answer.

like image 4
Dimitre Novatchev Avatar answered Oct 20 '22 18:10

Dimitre Novatchev