2011-10-25 26 views
6

Tengo problemas para entender qué almacena exactamente en childNodes. Idealmente, me gustaría hacer otra xquery en cada uno de los nodos secundarios, pero parece que no puedo entenderlo. Aquí está mi escenario: datos:¿Atravesar nodos secundarios con PHP DOMXpath?

<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> 

Y el código:

$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? } 

Para cada elemento de "algo" (es decir, $ n) Quiero tener acceso a los valores de las dos piezas de texto y el href. Intenté usar childNode y otra xquery pero no pude hacer que funcionara nada. ¡Cualquier ayuda sería muy apreciada!

Respuesta

10

Sí se puede ejecutar otra consulta XPath, algo así:

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

    echo $other_nodes->length; 
} 

Esto le dará el div interior con el somethingelse clase, el segundo argumento de la xpath- $> método de consulta dice que consultar a tomar este nodo como contexto, véase más http://fr2.php.net/manual/en/domxpath.query.php

+0

Gracias @TrexXx, pero cuando se utiliza "$ other_nodes-> nodeValue" No veo nada. ¿No está comenzando de nuevo en el elemento raíz? Originalmente pensé que sería algo como esto: '$ other_nodes = $ n-> query ('div [@ class =" somethingelse "]')'; – Bryan

+0

'$ other_nodes' es una lista de nodos, por lo que primero tendrá que obtener un elemento (un nodo) y luego obtener su valor. Algo así como '$ other_nodes-> item (0) -> nodeValue'. – TrexXx

+0

'$ other_nodes' termina conteniendo información desde afuera de' $ n' (es decir, desde otros elementos "algo"); no debería ser el camino, ¿verdad? ¿Conoce algún otro enfoque que no requiera volver a consultar el elemento raíz? – Bryan

3

Trexx lo tenía, pero se perdió la última frase de la pregunta: ¿

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

Si understan d su pregunta correctamente, funcionó cuando usé la expresión descendiente ::. Pruebe esto:

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

    echo $other_nodes->length; 
    echo $other_nodes->item(0)->nodeValue; 
} 

Aunque a veces es suficiente para combinar consultas utilizando la // expresión de ruta para reducir su búsqueda. La // expresión de ruta selecciona nodos en el documento a partir del nodo actual que coincide con el selector.

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

A continuación, desplácese por las cosas que necesita. Espero que esto ayude.

+0

Gracias, he estado dando vueltas para obtener el resultado de los padres >> hijos, esto funciona para mí – sarvesh

0

Aquí es un fragmento de código que le permite acceder a la información contenida en cada uno de los nodos con atributos de clase "algo":

$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);` 
Cuestiones relacionadas