2013-04-11 16 views
6

Używam simpile_html_dom do uzyskiwania elementów stron html. Mam niektóre elementy div, takie jak ten. Wszystko, co chcę, to uzyskać zdanie "W porządku dzięki" w każdym div (który nie jest wewnątrz żadnego podelementu). Jak mogę to zrobić?Pobieranie zawartości elementu za pomocą simpe-html-dom

<div class="right"> 
<h2> 
<a href="">Hello</a> 
</h2> 
<br/> 
<span>How Are You?</span> 
<span>How Are You?</span> 
<span>How Are You?</span> 
Fine Thanks 
</div> 
+0

skończyłeś próbował żadnego kodu? –

+0

chcesz uzyskać lub chcesz wstawić w dziale? – liyakat

+0

Czy umieścisz jeszcze 2 elementy div? lub czy to powtarza się jak element div wysłany? –

Odpowiedz

1

Tam nie jest zbudowany w sposób do odczytu właściwości tekstu w simple_html_dom.php
Ale to powinno działać;

include 'parser.php'; 

$html = str_get_html('<div class="right"> 
<h2> 
<a href="">Hello</a> 
</h2> 
<br/> 
<span>How Are You?</span> 
<span>How Are You?</span> 
<span>How Are You?</span> 
Fine Thanks 
</div>'); 

function readTextNode($element){ 
    $local = $element; 
    $childs = count($element->childNodes()); 
    for($i = 0; $i < $childs; $i++) 
     $local->childNodes($i)->outertext = ''; 
    return $local->innertext; 
} 

echo readTextNode($html->find('div.right',0)); 
+0

To po prostu okropne, bez urazy; modyfikowanie drzewa w celu wyodrębnienia czegoś jest cofnięte i nie powinno być konieczne w odpowiedniej bibliotece. Westchnienie. –

0
public function removeNode($selector) 
{ 
    foreach ($html->find($selector) as $node) 
    { 
    $node->outertext = ''; 
    } 

$this->load($this->save());   
} 

Ta funkcja służy do usuwania elementu H2 i rozłożone div. Następnie pobierz dane elementu div.

Przekierowanie: Simple HTML Dom: How to remove elements?

2

To powinny być po prostu $html->find('div.right > text'), ale to nie będzie działać, ponieważ prosty HTML DOM Parser nie wydają się popierać bezpośrednie zapytania potomka.

Najpierw należy znaleźć wszystkie elementy <div> i przeszukać węzły podrzędne dla węzła tekstowego. Niestety, metoda ->childNodes() jest odwzorowana na ->children() i dlatego zwraca tylko elementy.

Rozwiązaniem roboczym jest wywołanie ->find('text') na każdym elemencie <div>, po czym wyniki zostaną przefiltrowane na podstawie węzła nadrzędnego.

foreach ($doc->find('div.right') as $parent) { 
    foreach ($parent->find('text') as $node) { 
     if ($node->parent() === $parent && strlen($t = trim($node->plaintext))) { 
      echo $t, PHP_EOL; 
     } 
    } 
} 

Korzystanie DOMDocument, to wyrażenie XPath zrobi taką samą pracę bez bólu:

$doc = new DOMDocument; 
$doc->loadHTML($content); 
$xp = new DOMXPath($doc); 

foreach ($xp->query('//div/text()') as $node) { 
    if (strlen($t = trim($node->textContent))) { 
     echo $t, PHP_EOL; 
    } 
} 
+0

Prawdopodobnie ale OP mówi, że musi użyć 'simpile_html_dom'. Oczywiście XPath ma lepsze rozwiązanie niż my wszyscy. –

+1

@silentboy Cóż, dlatego moja odpowiedź ma obie; Powinienem rozpocząć kampanię anty-simple_html_dom :) –

+0

Nie obwiniaj prostych, tak naprawdę nie ma sposobu, aby dostać się do tego węzła tekstowego (i prawdopodobnie nie powinno być) w css. – pguardiario

1

chciałbym przejść do phpquery dla tego jednego. Trzeba jeszcze używać DOM ale nie zbyt bolesne:

require('phpQuery.php'); 

$html =<<<EOF 
<div class="right"> 
<h2> 
<a href="">Hello</a> 
</h2> 
<br/> 
<span>How Are You?</span> 
<span>How Are You?</span> 
<span>How Are You?</span> 
Fine Thanks 
</div> 
EOF; 

$dom = phpQuery::newDocumentHTML($html); 

foreach($dom->find("div.right > *:last") as $last_element){ 
    echo $last_element->nextSibling->nodeValue; 
} 

Aktualizacja Te dni mam zalecające this simple replacement które nie pozwalają uniknąć brzydoty DOM:

$doc = str_get_html($html); 
foreach($doc->find('div.right > text:last') as $el){ 
    echo $el->text; 
} 
Powiązane problemy