Domanda

Sto analizzando i risultati XML da una chiamata API usando PHP e 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');
 }

Funziona ma c'è un modo per accedere sia al testo che all'attributo da una query? E se sì, come si arriva a questi elementi una volta eseguita la query?

È stato utile?

Soluzione

Dopo aver guardato in giro mi sono imbattuto in questa soluzione. In questo modo posso ottenere il testo dell'elemento e accedere a qualsiasi attributo del nodo.

$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');
}

Altri suggerimenti

Un'unica espressione XPath che selezionerà entrambi i nodi di testo di " a: Books " e il loro " DeweyDecimal " attributo, è il seguente

// a: Libri / testo () | // a: Libri / @ DeweyDecimal

Nota l'uso dell'operatore sindacale XPath nell'espressione sopra.

Un'altra nota : cerca di evitare di utilizzare il " // " abbreviazione in quanto potrebbe far attraversare l'intero documento XML e quindi è molto costoso. Si consiglia di utilizzare un'espressione XPath più specifica (ad esempio costituita da una catena di passaggi di posizione specifici) sempre quando è nota la struttura del documento XML.

Se stai solo recuperando valori dal tuo documento XML, SimpleXML potrebbe essere la soluzione più snella, più veloce e più adatta alla memoria:

$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'];
}

Potresti richiedere la concatenazione?

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

XSLT è un linguaggio di espressione in sé e puoi creare qualsiasi formato specifico di valore di ritorno desideri all'interno dell'espressione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top