You can use a PHP function from XPath to iterate through each character to do a case fold:
function fold_case($t=''){
// IF BLANK, RETURN BLANK
if($t==''){return'';}
// FOR EACH CODEPOINT, FOLD CASE & ADD TO NEW TEXT
$n='';
$i=IntlBreakIterator::createCodePointInstance();
$i->setText($t);
foreach($i->getPartsIterator() as$c)
{$n.=IntlChar::foldCase($c,IntlChar::FOLD_CASE_DEFAULT);}
// RETURN NEW TEXT
return$n;
}
An alternative uses the transliterator to convert to lowercase:
function lower_case($t=''){return($t==''?B:transliterator_transliterate('Lower',$t));}
Unfortunately, PHP does not support the Fold
ID to replace Lower
to make the transliterator do full case-folding rather than the per codepoint iteration.
These can be enabled in the XSLT processor by:
$t=new XSLTProcessor;
$t->importStylesheet($s);
$t->registerPHPFunctions(['fold_case','lower_case']);
They can be included in any XPath expression, as in:
<xsl:variable name="search_text" select="php:function('fold_case',$text)"></xsl:variable>
If the text is in an attribute, force it to be a string by passing string(@text)
.
This uses the intl
extension, which needs to be enabled in cPanel, or however they are enabled on your platform.
To use PHP functions in an XSLT file, specify at the top of the file:
<?xml version="1.0" encoding="utf-8"?>
<x:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl"
exclude-result-prefixes="php">
Note that if you are going to use the XSLT file only with PHP, you can shorten the xsl
and php
namespace prefixes to one character like:
<?xml version="1.0" encoding="utf-8"?>
<x:stylesheet version="1.0"
xmlns:x="http://www.w3.org/1999/XSL/Transform"
xmlns:p="http://php.net/xsl"
exclude-result-prefixes="p">
This can reduce the size of a large XSLT file and save a lot of typing by prefixing using only x:
and p:
as namespaces respectively.
While PHP is not likely to upgrade their XML, XSLT or XPath processors from version 1.0, being able to call user or inbuilt PHP functions from XPath provides a lot more flexibility, such as having actual mutable variables, or an inline ternary if function like php:function('iif',(@i),string(@i),string(@c))
(though both arguments are evaluated like in VB6's IIF
) for use in xsl:for-each
or xsl:sort
statements.
See https://smallsite-design.com/art/a-php-functions-in-xslt/ for some guidance in how to reliably pass XML elements and attributes to PHP functions in XPath.