Извлекает как текст, так и атрибут данного узла с помощью Xpath

StackOverflow https://stackoverflow.com/questions/141913

  •  02-07-2019
  •  | 
  •  

Вопрос

Я анализирую XML-результаты вызова API с использованием PHP и xpath.

 $dom = new DOMDocument();
 $dom->loadXML($response->getBody());

 $xpath = new DOMXPath($dom);
 $xpath->registerNamespace("a", "http://www.example.com");

 $hrefs = $xpath->query('//a:Books/text()', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookTitle[$i] = $hrefs->item($i)->data;
 }

 $hrefs = $xpath->query('//a:Books', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
 }

Это работает, но есть ли способ, которым я могу получить доступ как к тексту, так и к атрибуту из одного запроса?И если да, то как вы получаете доступ к этим элементам после выполнения запроса?

Это было полезно?

Решение

Немного осмотревшись, я наткнулся на это решение.Таким образом, я могу получить текст элемента и получить доступ к любым атрибутам узла.

$hrefs = $xpath->query('//a:Books', $dom);

for ($i = 0; $i < $hrefs->length; $i++) {
    $arrBookTitle[$i] = $hrefs->item($i)->nodeValue;
    $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
}

Другие советы

Одно единственное выражение XPath, которое будет выбирать как текстовые узлы "a: Books", так и их атрибут "DeweyDecimal", является следующим

//a:Books/text() | //a:Books/@DeweyDecimal

Обратите внимание использование оператора объединения XPath в приведенном выше выражении.

Еще одна записка:старайтесь избегать использования аббревиатуры "//", поскольку это может привести к обходу всего XML-документа и, следовательно, обойдется очень дорого.Рекомендуется использовать более конкретное выражение XPath (например, состоящее из цепочки определенных шагов определения местоположения) всегда, когда известна структура XML-документа.

Если вы просто извлекаете значения из своего XML-документа, SimpleXML возможно, это более компактное, быстрое и дружественное к памяти решение:

$xml=simplexml_load_string($response->getBody());
$xml->registerXPathNamespace('a', 'http://www.example.com');
$books=$xml->xpath('//a:Books');
foreach ($books as $i => $book) {
    $arrBookTitle[$i]=(string)$book;
    $arrBookDewey[$i]=$book['DeweyDecimal'];
}

Не могли бы вы запросить конкатенацию?

$xpath->query('concat(//a:Books/text(), //a:Books/@DeweyDecimal)', $dom);

XSLT сам по себе является языком выражений, и вы можете создать любой конкретный формат возвращаемого значения, который вы хотите, из выражения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top