Come get il valore di tutti i nodes di text tra i nodes span

Ho la seguente struttura html

<span class="x">a</span> <br> • first <br> • Second <br> • second <br> • third <br> <br> <span class="x">b</span> 

Ho bisogno di get tutto il valore del text (separato da virgole) che si verifica tra i nodes span, ovvero primo, secondo, secondo, terzo

Come si può fare usando xpath, dom

È ansible eseguire query su questi elementi utilizzando XPath, ma è necessario eseguire la "pulizia" di questi punti elenco in PHP poiché SimpleXML support solo XPath 1.0 senza funzionalità di modifica estesa della string.

La cosa più importnte è l'espressione XPath, che spiegherò in dettaglio:

  • //span[text()='a']/following::text() : recupera tutti i nodes di text dopo lo span con il contenuto "a"
  • [. = //span[text()='b']/preceding::text()] [. = //span[text()='b']/preceding::text()] Confronta ciascuno di essi con il set di nodes di text prima dello span con il contenuto "b"

Ed ecco il codice completo, potresti voler investire un po 'più di impegno nella rimozione del punto elenco. Assicurati che PHP lo stia valutando come UTF-8, altrimenti otterrai Mojibake invece del punto elenco .

 <?php $html = ' <span class="x">a</span> <br> • first <br> • Second <br> • second <br> • third <br> <br> <span class="x">b</span></wrap> '; libxml_use_internal_errors(true); $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->strictErrorChecking = false; $dom->recover = true; $dom->loadHTML($html); $xpath = new DOMXPath($dom); $results = $xpath->query("//span[text()='a']/following::text()[. = //span[text()='b']/preceding::text()]"); foreach ($results as $result) { $token = trim(str_replace('•', '', $result->nodeValue)); if ($token) $tokens[] = $token; } echo implode(',', $tokens); ?> 

La tua struttura html di <br> seguita da punti elenco può essere facilmente convertita in una list non ordinata <ul></ul> senza modificare il layout della tua pagina.

Quindi puoi select il text di tutti gli elementi dell'elenco <li></li> e la virgola li delimita. Ho incluso un esempio in questo jsFiddle .

Per get questo text puoi usare questo:

 var nodes = $('ul > li').map(function() { return $(this).text(); }).toArray().join(","); 

where i nodes sono la string 'first,Second,second,third' .