Пробел в PHP-запросе xpath (новый SimpleXMLElement) - PullRequest
0 голосов
/ 30 ноября 2018

Я получаю вывод XML и преобразовываю его с новым SimpleXMLElement.Выход представляет собой массив.Таким образом, XML-элемент - это $ xml.

print_r($xml->xpath('categories[categories_name="Toners"]/childs/categories[categories_name="Color LaserJet"]'));

Во втором [category_name] значение имеет пробел в строке.Там идет что-то не так из-за места.Я не получаю никакой возвращенной информации, если я удаляю значение с другим существующим значением без пробела, я получаю нужную информацию.

Что я могу сделать?

1 Ответ

0 голосов
/ 01 декабря 2018

Разбивка вопроса на небольшой воспроизводимый пример:

$xml = <<<'XML'
<books>
  <book><title>A Title</title></book>
  <book><title>  A Title  </title></book>  
</books>
XML;
$books = new SimpleXMLElement($xml);

echo  "String compare:\n";
foreach ($books->xpath('//book[title="A Title"]') as $book) {
  var_dump((string)$book->title);
} 

Вывод:

String compare: 
string(7) "A Title"

Второй заголовок книги содержит предшествующие и последующие пробелы, поэтому простое сравнение строк не будетсопоставьте это.Один из способов решить эту проблему - использовать normalize-space().Эта функция Xpath заменит любую последовательность пробелов одним пробелом и удалит предшествующие / последующие пробелы.Это мало что дает, но в большинстве случаев это не имеет значения.

echo  "\nwith normalize-space():\n";
foreach ($books->xpath('//book[normalize-space(title)="A Title"]') as $book) {
  var_dump((string)$book->title);
}

Вывод:

with normalize-space(): 
string(7) "A Title" 
string(11) " A Title "

Теперь он соответствует обоим заголовкам, но будет соответствовать чему-то вроде A Title также.

Другое решение позволяет вам больше контролировать, но требует DOM.В DOM вы можете зарегистрировать функции PHP, которые можно вызывать из выражений XPath.Это могут быть существующие функции или ваши собственные.Вы можете сделать trim() доступным:

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPhpFunctions(['trim']);

echo  "\nCall back into PHP:\n";
$expression = '//book[php:functionString("trim", string(title)) = "A Title"]';
foreach($xpath->evaluate($expression) as $node) {
  var_dump($xpath->evaluate('string(title)', $node));
}

С вашей собственной функцией обратного вызова вы можете делать что-либо, например, совпадения с RegEx или транслитерацию строк в Юникоде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...