-->

case-insensitive matching in xpath?

2019-01-02 21:27发布

问题:

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.

回答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.



回答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')]


回答3:

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")];


回答4:

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



回答5:

You mentioned that PHP solutions were acceptable, and PHP does offer a way to accomplish this even though it only supports XPath v1.0. You can extend the XPath support to allow PHP function calls.

$xpathObj = new DOMXPath($docObj);
$xpathObj->registerNamespace('php','http://php.net/xpath'); // (required)
$xpathObj->registerPhpFunctions("strtolower"); // (leave empty to allow *any* PHP function)
$xpathObj->query('//CD[php:functionString("strtolower",@title) = "empire burlesque"]');

See the PHP registerPhpFunctions documentation for more examples. It basically demonstrates that "php:function" is for boolean evaluation and "php:functionString" is for string evaluation.



标签: