Intereting Posts
Извлечь значения из массива с помощью вложенного цикла foreach PHP Передача переменных между двумя файлами php exec () возвращает пустое значение Закрытие соединения MySQL после каждого запроса Ошибка MySQL / PHP: Разрешено только одно использование каждого адреса сокета (протокол / сетевой адрес / порт) Отправка изображения из программы C # на веб-страницу PHP для отображения Как открыть файл из строки X в строку Y в PHP? Предварительная загрузка изображений с использованием PHP и jQuery – массив с запятой? PHP: переменная не работает внутри функции? Запрос Mysqli в функции – PHP Как отправить данные формы с моего сайта на мой адрес электронной почты? Возможно ли зарегистрировать функцию обратного вызова для waitUntilDBInstanceAvailable ()? Как прослушивать TCP-порт с помощью PHP? У проблемы $ _REQUEST проблемы с безопасностью? Могу ли я сказать Apache, чтобы сделать внутреннюю переадресацию с PHP?

Как я могу использовать XPath для выполнения поиска без учета регистра и поддержки неанглийских символов?

Я выполняю поиск в XML-файле, используя следующий код:

$result = $xml->xpath("//StopPoint[contains(StopName, '$query')]"); 

Где $ query – поисковый запрос, а StopName – это имя остановки шины. Проблема в том, что он чувствителен к регистру.

И не только это, я бы также мог искать с неанглийскими персонажами, такими как ÆØÅæøå, чтобы вернуть норвежские имена.

Как это возможно?

В XPath 1.0 (что, я считаю, лучшее, что вы можете получить с помощью PHP SimpleXML), вам нужно будет использовать функцию translate() для создания вывода из строчного ввода из смешанного ввода.

Для удобства я бы обернул его в такую ​​функцию:

 function findStopPointByName($xml, $query) { $upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"; // add any characters... $lower = "abcdefghijklmnopqrstuvwxyzæøå"; // ...that are missing $arg_stopname = "translate(StopName, '$upper', '$lower')"; $arg_query = "translate('$query', '$upper', '$lower')"; return $xml->xpath("//StopPoint[contains($arg_stopname, $arg_query)"); } 

В качестве меры санитарии я либо полностью запретил бы, либо избежал одиночных кавычек в $query , потому что они сломают вашу строку XPath, если они будут проигнорированы.

В XPath 2.0 вы можете использовать функцию lower-case() , которая является unicode, поэтому она отлично обрабатывает символы, отличные от ASCII.

 contains(lower-case(StopName), lower-case('$query')) 

Для доступа к XPath 2.0 вам нужен синтаксический анализатор XSLT 2.0. Например, SAXON . Вы можете получить к нему доступ с PHP через JavaBridge.

Неанглийские имена не должны быть проблемой. Просто добавьте их в свой XPath. (XML определяется как использование Unicode).

Что касается нечувствительности к регистру, …

XPath 1.0 включает следующую инструкцию :

Две строки равны тогда и только тогда, когда они состоят из одной и той же последовательности символов UCS.

Поэтому даже использование явных предикатов для локального имени не поможет.

XPath 2 включает функции для сопоставления фреймов. Например, fn: верхний регистр


Дополнительно: использование функции перевода XPath должно допускать фальсификацию фреймов в XPath 1, но на вход нужно будет указать каждую кодовую точку кода, которую вам и вашим пользователям когда-либо понадобится:

 "test" = translate($inputString, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ") 

К тому же:

$ xml-> xpath ("// StopPoint [содержит (StopName, '$ query')]");

Вам нужно будет вычеркнуть любые символы апострофа из запроса $, чтобы не нарушать ваше выражение.

В XPath 2.0 вы можете удвоить цитату, используемую в разделителе, чтобы поместить эту цитату в строковый литерал, но в XPath 1.0 невозможно включить разделитель в строку.