2013-05-24 18 views
16

Esiste un modo per eseguire una query xpath su un DOMNode? O almeno convertirlo in un DOMXPath?Come si esegue una query XPath su un DOMNode?

<html> 
    ... 
    <div id="content"> 
    ... 
    <div class="listing"> 
     ... 
     <div></div> 
     <div></div> 
     <div class='foo'> 
      <h3>Get me 1</h3> 
      <a>and me too 1</a> 
     </div> 
    </div> 
    <div class="listing"> 
     ... 
     <div></div> 
     <div></div> 
     <div class='foo'> 
      <h3>Get me 2</h3> 
      <a>and me too 1</a> 
     </div> 
    </div> 
    .... 
    </div> 
</html> 

Questo è il mio codice. Sto cercando di ottenere un elenco di array con i valori di h3 e tag in ogni array. Per fare ciò, avevo bisogno di ottenere ogni elenco, e quindi ottenere il valore di h3 e di un tag in ogni elenco.

$html_dom = new DOMDocument(); 
@$html_dom->loadHTML($html); 
$x_path = new DOMXPath($html_dom); 

$nodes= $x_path->query("//div[@id='content']//div[@class='listing']"); 

foreach ($nodes as $node) 
{ 
    // I want to further dig down here using query on a DOMNode 
} 
+0

mentre è possibile interrogare da un nodo particolare, puoi semplicemente interrogare tutti i div con la classe pippo. O l'ultimo figlio div dell'elenco e ottieni immediatamente i valori. – Gordon

+0

Stavo pensando di ottenere le voci prima e poi interrogare i valori al suo interno in modo da poterlo inserire facilmente in una matrice in quella struttura. Ma suppongo che potrei semplicemente abbinare gli indici dei risultati di h3 e a se voglio. – arvinsim

risposta

26

Passare il nodo di come secondo argomento al DOMXPath::query

contextnode: Il contextnode opzionale può essere specificato per fare query XPath relative. Per impostazione predefinita, le query sono relative all'elemento radice.

Esempio:

foreach ($nodes as $node) { 
    foreach ($x_path->query('h3|a', $node) as $child) { 
     echo $child->nodeValue, PHP_EOL; 
    } 
} 

Questo utilizza la UNION operator per un risultato di

Get me 1 
and me too 1 
Get me 2 
and me too 1 

Se non è necessario alcun interrogazione complesso, si può anche fare

foreach ($nodes as $node) { 
    foreach ($node->getElementsByTagName('a') as $a) { 
     echo $a->nodeValue, PHP_EOL; 
    } 
} 

O anche ripetendo i nodi figlio (notare che questo io è comprensivo di tutti i nodi di testo)

foreach ($nodes as $node) { 
    foreach ($node->childNodes as $child) { 
     echo $child->nodeName, PHP_EOL; 
    } 
} 

Tuttavia, tutto questo è non necessari dal momento che è possibile recuperare questi nodi direttamente:

$nodes= $x_path->query("/html/body//div[@class='listing']/div[last()]"); 

foreach ($nodes as $i => $node) { 
    echo $i, $node->nodeValue, PHP_EOL; 
} 

vi darà due nodi nel l'ultimo figlio div di tutti i div con un valore di attributo di classe dell'annuncio e uscita i valori del nodo di testo combinati, compresi gli spazi

0 
      Get me 1 
      and me too 1 

1 
      Get me 2 
      and me too 1 

Analogamente, il seguente

"//div[@class='listing']/div[last()]/node()[name() = 'h3' or name() = 'a']" 

vi darà la H3 quattro bambino e nodi A e uscita

0Get me 1 
1and me too 1 
2Get me 2 
3and me too 1 

Se avete bisogno di differenziare questi da nome mentre l'iterazione su di loro, si può fare

foreach ($nodes as $i => $node) { 
    echo $i, $node->nodeName, $node->nodeValue, PHP_EOL; 
} 

che sarà poi dare

0h3Get me 1 
1aand me too 1 
2h3Get me 2 
3aand me too 1 
+0

e se volesse memorizzare h3 e una in variabili diverse come questo http://stackoverflow.com/questions/43131400/xpath-query-get-child-nodes-in-a-parent-node-using-a- ciclo continuo – DragonFire

5

Fornire il proprio $node come nodo di contesto.

foreach ($nodes as $node) 
{ 
    $morenodes = $x_path->query(".//h3", $node); 
} 

Vedi $contextnode nel manuale: http://php.net/manual/en/domxpath.query.php

+0

Quando ho fatto quella soluzione, mi sembra di ottenere gli stessi risultati quando ho fatto il giro del nodelist ... Continuo a ricevere i valori per il primo elenco – arvinsim

+0

Qual è la query xpath che stai usando? Modifica: all'interno del ciclo che è. – EPB

+3

Sono andato avanti e modificato con una query di esempio che avevo usato inizialmente per testare la mia risposta. A partire da '.' è importante se si intende usare' // 'per avviare la query, che apparentemente è sempre relativa a root. – EPB

1

Solo per renderlo completo, c'è unMetodoche restituisce xpath di quel nodo.Quindi puoi anche usare $x_path->query($node->getNodePath().'//h3')

Problemi correlati