2011-10-25 18 views
6

Ho difficoltà a capire cosa è esattamente memorizzato in childNodes. Idealmente mi piacerebbe fare un altro xquery su ciascuno dei nodi figlio, ma non riesco a farlo sembrare chiaro. Ecco il mio piano d'azione: dati:Attraversare i nodi figlio con DOMXpath PHP?

<div class="something"> 
    <h3> 
     <a href="link1.html">Link text 1</a> 
    </h3> 
    <div class"somethingelse">Something else text 1</div> 
</div> 
<div class="something"> 
    <h3> 
     <a href="link2.html">Link text 2</a> 
    </h3> 
    <div class"somethingelse">Something else text 2</div> 
</div> 
<div class="something"> 
    <h3> 
     <a href="link3.html">Link text 3</a> 
    </h3> 
    <div class"somethingelse">Something else text 3</div> 
</div> 

E il codice:

$html = new DOMDocument(); 
$html->loadHtmlFile($local_file); 
$xpath = new DOMXPath($html); 
$nodelist = $xpath->query("//div[@class='something']"); 
foreach ($nodelist as $n) { 
    Can I run another query here? } 

Per ogni elemento di "qualcosa" (cioè, $ n) voglio accedere i valori delle due parti di testo e l'href. Ho provato a utilizzare childNode e un'altra xquery ma non ho potuto ottenere nulla per funzionare. Qualsiasi aiuto sarebbe molto apprezzato!

risposta

10

Sì, è possibile eseguire un'altra query XPath, qualcosa di simile:

foreach ($nodelist as $n) 
{ 
    $other_nodes = $xpath->query('div[@class="somethingelse"]', $n); 

    echo $other_nodes->length; 
} 

questo modo si ottiene la div interno con il somethingelse classe, il secondo argomento del $ xpath-> metodo di query dice di interrogare a prendere questo nodo come contesto, vedere di più http://fr2.php.net/manual/en/domxpath.query.php

+0

Grazie @TrexXx, ma quando uso "$ other_nodes-> nodeValue" Non vedo niente Non si sta ricominciando dall'elemento principale? Originariamente pensavo che fosse qualcosa del genere: '$ other_nodes = $ n-> query ('div [@ class =" somethingelse "]')'; – Bryan

+0

'$ other_nodes' è un elenco di nodi, quindi prima devi ottenere un oggetto (un nodo) e quindi ottenere il suo valore. Qualcosa come '$ other_nodes-> item (0) -> nodeValue'. – TrexXx

+0

'$ other_nodes' finisce per contenere informazioni esterne a' $ n' (ad esempio da altri elementi "qualcosa"); non dovrebbe essere il modo, giusto? Conosci qualche altro approccio che non richiede di tornare a interrogare l'elemento radice? – Bryan

3

Trexx l'aveva, ma ha mancato l'ultima frase della questione:

foreach ($nodelist as $n){ 
    $href = $xpath->query('h3/a', $n)->item(0)->getAttribute('href'); 
    $a_text = $xpath->query('h3/a', $n)->item(0)->nodeValue; 
    $div_text = $xpath->query('div', $n)->item(0)->nodeValue; 
} 
2

Se understan d la tua domanda correttamente, ha funzionato quando ho usato il discendente :: espressione. Prova questo:

Anche se a volte è sufficiente combinare le query utilizzando l'espressione // path per restringere la ricerca. L'espressione // path seleziona i nodi nel documento a partire dal nodo corrente che corrisponde al selettore.

$nodes = $xpath->query('//div[@class="some-descendant"]//div[@class="some-descendant-of-that-descendant"]'); 

Quindi passa attraverso quelli per il materiale di cui hai bisogno. Spero che questo ti aiuti.

+0

Grazie, sono stato in loop per ottenere genitore >> risultato figlio, questo lavoro per me – sarvesh

0

Ecco un frammento di codice che consente di accedere alle informazioni contenute all'interno di ciascuno dei nodi con attributo class "qualcosa":

$nodes_tracker = 0; 
$nodes_array = array(); 
foreach($nodelist as $n){ 
    $info = $xpath->query('//h3//a', $n)->item($nodes_tracker)->nodeValue; 
    $extra_info = $xpath->query('//div[@class="somethingelse"', $n)->item($nodes_tracker)->nodeValue; 
    array_push($nodes_array, $info. ' - '. $extra_info . '<br>'); //Add each info to array 
    $nodes_tracker++; 
} 
print_r($nodes_array);`