2009-12-19 30 views
16

Próbuję parsować niektóre HTML z DOM w PHP, ale mam pewne problemy. Po pierwsze, na wypadek, gdyby to zmieniło rozwiązanie, HTML, który mam, nie jest pełną stroną, a raczej jest tylko jego częścią.Jak analizować częściowy kod HTML?

<!-- This is the HTML that I have --><a href='/games/'> 
<div id='game'> 
<img src='http://images.example.com/games.gif' width='300' height='137' border='0'> 
<br><b> Game </b> 
</div> 
<div id='double'> 
<img src='http://images.example.com/double.gif' width='300' height='27' border='0' alt='' title=''> 
</div> 
</a> 

Teraz próbuję uzyskać tylko element div o identyfikatorze double. Próbowałem poniższy kod, ale wydaje się, że nie działa poprawnie. Co mogę robić źle?

//The HTML has been loaded into the variable $html 
$dom=new domDocument; 
$dom->loadHTML($html); 
$dom->preserveWhiteSpace = false; 
$keepme = $dom->getElementById('double'); 

$contents = '<div style="text-align:center">'.$keepme.'</a></div>'; 
echo $contents; 
+0

Co on robi lub nie robi? –

Odpowiedz

13

myślę DOMDocument::getElementById nie zadziała w Twoim przypadku: (cytowanie)

Aby ta funkcja działa, będzie potrzeba albo ustawić niektóre ID atrybuty z DOMElement::setIdAttribute lub DTD, które definiuje atrybut o wartości typu ID.
W późniejszym przypadku, użytkownik będzie musiał zweryfikować swój dokument za pomocą DOMDocument::validate lub DOMDocument->validateOnParse przed za pomocą tej funkcji.


Rozwiązanie, które może działać używa jakiś XPath query wyodrębnić element, którego szukasz.

Przede wszystkim niech załadować część HTML, jak po raz pierwszy zrobił:

$dom=new domDocument; 
$dom->loadHTML($html); 
var_dump($dom->saveHTML()); 

var_dump jest tutaj tylko udowodnić, że część HTML został załadowany pomyślnie - sądząc po jego wyjściu, to ma .


Następnie instanciate klasę DOMXPath i użyć go do kwerendy dla elementu chcesz uzyskać:

$xpath = new DOMXpath($dom); 
$result = $xpath->query("//*[@id = 'double']"); 
$keepme = $result->item(0); 

Mamy teraz do elementu chcesz ;-)


Ale , aby wstrzyknąć zawartość HTML w inny segment HTML, musimy najpierw pobrać jego treść HTML.

nie pamiętam żadnego "łatwy" sposób, aby to zrobić, ale coś takiego sould rade:

$tempDom = new DOMDocument(); 
$tempImported = $tempDom->importNode($keepme, true); 
$tempDom->appendChild($tempImported); 
$newHtml = $tempDom->saveHTML(); 
var_dump($newHtml); 

I ... Mamy zawartości HTML swojej double<div>:

string '<div id="double"> 
<img src="http://images.example.com/double.gif" width="300" height="27" border="0" alt="" title=""> 
</div> 
' (length=125) 


teraz po prostu trzeba robić, co chcesz z nim ;-)

0

HTML Tidy powinien być zdolny do „korygowania” połamane i fragmentarycznych dokumentów HTML, zamieniając je w coś, co może być analizowany z innymi narzędziami

http://devzone.zend.com/article/761

Rozszerzenie Tidy jest nowa PHP 5, i jest dostępny w wersji PHP 5.0b3 w górę. Oparty jest on na bibliotece TidyLib i pozwala deweloperowi na walidację, naprawę i przetwarzanie dokumentów HTML, XHTML i XML z poziomu PHP.

3

Od DomDocument::getElementById

Aby ta funkcja działa, będziesz potrzeba albo ustawić niektóre atrybuty ID z DOMElement :: setIdAttribute lub DTD który definiuje atrybut być typu ID . W późniejszym przypadku użytkownik będzie musiał zweryfikować swój dokument za pomocą DOMDocument :: validate lub DOMDocument-> validateOnParse przed za pomocą tej funkcji.

Dla niektórych dodatkowych informacji

A skoro ktoś będzie wspomnieć robi to z wyrażenia regularnego, prędzej czy później, oto wzór można użyć: /<div id='double'>(.*)<\/div>/simU

W uzupełnieniu można po prostu użyć zwykłych funkcji łańcuchowych do wyodrębnienia części div, np.

$div = strstr($html, '<div id="double">'); 
$div = substr($div, 0, strpos($div, '</div>') + 6); 
echo $div; 

Chociaż zgadzam się, że nie należy korzystać z funkcji regex lub ciąg dla parsowania HTML lub XML, uważam, że to absolutnie w porządku to zrobić, tak długo, jak tylko problemem jest to, aby ten jeden div z fragmentów. Nie komplikuj.

+1

Oczywiście, jeśli nie ma zagnieżdżonych znaczników div.Wyrażenia regularne są * nie * do parsowania html. – troelskn

+0

Zgodziłbym się, jeśli on faktycznie * analizował * ten fragment. ale po prostu chce wydobyć z niego jedną wyraźnie określoną część. To nie jest tak, że on przemierza DOM, więc myślę, że dobrze jest traktować fragment jako ciąg. – Gordon

+0

Poza tym już wskazałem mu SimpleHTML w pierwszym zdaniu. – Gordon

0

Dokument XML może mieć tylko jeden element na poziomie głównym. Prawdopodobnie parser HTML ma podobne wymagania. Spróbuj zawinąć treść w tagu <body/>.

Wygląda na coś innego. This page opisuje, co może być przyczyną. Zalecam użycie XPath, aby uzyskać element.

-1

Fragment to HTML, ale do parsowania DOM należy XHTML. Każdy otwarty znacznik musi zostać zamknięty.

W twoim przypadku to oznacza, że ​​należy wymienić <br> z <br /> i <img ... > z <img ... />

+0

To nie jest prawda. $ dom-> loadHTML ("


") działa dobrze i nie przepuszcza parsowania. W rzeczywistości, $ dom-> saveXML() wyświetli wynik z poprawnie zamkniętymi tagami. –

+0

Wszystko zależy od używanej biblioteki. W python: xml.dom.minidom.parseString ("
") -> zwraca wyjątek. xml.dom.minidom.parseString ("
") działa. Wolałbym, aby dane wejściowe we właściwym formacie były na pierwszym miejscu niż poleganie na bibliotece, aby przeanalizować niepoprawne dane wejściowe zgodnie z oczekiwaniami. – filippo