Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] DOMDocument
Forum PHP.pl > Forum > Przedszkole
jimmix
Witam,

Mam taki plik html

  1. <tr>
  2. <th>
  3. Jeden
  4. </th>
  5. <td>
  6. Dwa
  7. <td>
  8. </tr>
  9.  
  10. <tr>
  11. <th>
  12. Trzy
  13. </th>
  14. <td>
  15. <p>Cztery</p><p>Piec</p>
  16. <td>
  17. </tr>
  18.  
  19.  


Obrabiam to kodem jak niżej

  1. $doc = new DOMDocument();
  2. $doc->loadHTMLFile( 'plik.htm' );
  3.  
  4. $elements = $doc->getElementsByTagName( "tr" );
  5.  
  6. //debug ($elements, "elements");
  7.  
  8. //print_r_tree($elements);
  9.  
  10. if (!is_null($elements)) {
  11. foreach ($elements as $element) {
  12.  
  13. $test = $doc->getElementsByTagName ('td');
  14.  
  15. echo "<br/>". $element->nodeName. ": ";
  16.  
  17. $nodes = $element->childNodes;
  18. //debug ($nodes, "nodes");
  19. foreach ($nodes as $node) {
  20.  
  21.  
  22. echo $node->nodeName . ' ' . $node->nodeValue. "#\n";
  23. }
  24. }


i dostaję wynik:

tr: th Jeden# td # Dwa
tr: th Trzy# td # CzteryPiec

Czy ktoś może wie dlaczego mi zjadło znacznik p? i jak to zmienić, aby rozbicie ten znacznik uwzględniało?
lukasz_p
Hej!

Spróbuj usunąć "<p>Piec</p>" i zobacz czy będzie działać tylko z jednym childNode dla td.
Wydaj mi się, że foreach ($nodes as $node) zwraca $node dla p jako tablice, no bo przecież parentNode (td) zawiera dwa childNode (p). Ale na 100% pewien nie jestem smile.gif
wNogachSpisz
Zredukuj elementy nie mające wpływu na błąd.
Ogranicz htmla tak aby zawierał wyłącznie elementy niezbędne do reprodukcji błędu.
Na koniec napisz jaki wynik otrzymujesz, a jakiego oczekujesz.

W przeciwnym razie masz małe szanse uzyskać pomoc od "prawdziwego gracza",
bo ten jest na wstępie znudzony odfiltrowywaniem nieistotnych informacji.
nospor
@wNogachSpisz już ty się tu w imieniu "prawdziwych graczy" nie wypowiadaj. Autor podał wszystko jak należy. Nic tu nie należy skracać

@jimmix <p> są dziećmi TD. Ty w pętli lecisz po dzieciach TR. Jak chcesz się dobrać do P to musisz go brać z dzieci TD.
nodeValue zwraca wartość tekstową stąd masz wynik jaki masz.
wNogachSpisz
Cytat(nospor @ 17.01.2012, 11:32:21 ) *
@wNogachSpisz już ty się tu w imieniu "prawdziwych graczy" nie wypowiadaj. Autor podał wszystko jak należy. Nic tu nie należy skracać

Dlaczego nie wypowiadaj? Jestem demokratycznie wybranym prezesem stowarzyszenia prawdziwych graczy.
Mi się całość zdaje zdeczka przydługawa.. może to kwestia ilości wierszy..
nospor
Ok, to następnym razem wymień członków tego stowarzyszenia coby autor wiedział czy opłaca mu sie stosować do twoich porad czy może jednak poczeka na wypowiedź prawdziwych userów tongue.gif

Cytat
.. może to kwestia ilości wierszy..
5 wierszy na skrzyż uważasz za długie? Ty chyba nie widziałeś co uzytkwownicy potrafią wrzucać do postów.
Dobra, koniec OFFTOPU.
zegarek84
już miałem odpowiadać ale przeczytałem drugi raz pytanie i nie jestem pewien co chciałeś uzyskać...

Chciałeś z osobna znaleźć elementy p zagnieżdżone w tr czy chciałeś uzyskać efekt innerHTML??
jimmix
Dziękuję za tak dużo odpowiedzi naprowadzających smile.gif
Zastosuję się do wskazówek i dam znać, co z tego wyszło.

Celem przetwarzania tego pliku html jest uzyskanie informacji znajdujacych się pomiędzy tagami wraz z samymi tagami, problem polega na tym że skrypt zwraca "CzteryPięć" bez spacji pomiędzy nimi, bez tagu p także. Starałem się ten temat opracować wcześniej na wyrażeniach regularnych ale raz to działało a raz nie bo np: ktoś dodał jakiś styl do tagu.

W między czasie tylko spytam bo jestem nowy w temacie DOM. - istnieje jakaś funkcja, która z automatu by przetworzyła html i zwróciła w postaci np zagnieżdżonych tablic gdzie klucz to byłaby nazwa tagu a wartość to tekst pomiędzy nim?
Pytam bo jak temat realizowałem na wyrażeniach regularnych to zrobiłem jeden wzorzec całości interesującego bloku, dodatkowo to co mnie interesowało umieściłem w nawiasy i miałem gotową tablicę z wyłuskanymi interesującymi danymi. Przy DOM mam wrażenie, że wzorzec nie jest tak skomplikowany, bo użwa się tagów ale zamiast tego trzeba budować pętle aby przeszukiwanie zagłębiało się do ostatniego znacznika - zgadza się?
zegarek84
Cytat(jimmix @ 17.01.2012, 22:22:50 ) *
Celem przetwarzania tego pliku html jest uzyskanie informacji znajdujacych się pomiędzy tagami wraz z samymi tagami, problem polega na tym że skrypt zwraca "CzteryPięć" bez spacji pomiędzy nimi, bez tagu p także.

skoro potrzebujesz coś na styl innerHTML z JS to luknij w manualu DOMDocument::saveXML

jeśli chodzi o resztę rzeczy to to, że masz bez spacji poniekąd jest poprawnie - zależy jak masz zapisane w kodzie a dlaczego funkcja ma domyślnie zmieniać treść...

jeśli chodzi o łatwość korzystania i np. jeśli preferujesz XPath to luknij w manualu, są tam odpowiednie funkcje...

a jeśli wolisz wyszukiwać na podstawie selektorów CSS to wstukaj w google PHPQuery (obudowuje to DOM z php i zwraca Ci elementy DOM)...

gdybyś kiedyś miał potrzebę parsowania naprawdę dużych plików gdzie możesz wyjść poza zakres pamięci to w google wstukaj "php sax", gdzie znajdziesz krótkie opisy jak korzystać z XML Parser - ale tu już musiałbyś przestawić swoje myślenie trochu na programowanie zdarzeniowe (po prostu odbierasz komunikaty i na nie reagujesz - gdzie nic nie stoi na przeszkodzie, by wprowadzić pamięć zdarzeń zaistniałych i sterowanie tym, co odczytujesz)

_____________________
OFTOPIC
swoją droga jak dawniej krystaloidem z PHP to wynik jaki podawałeś można było uzyskać tylko za pomocą .textContent a .nodeValue było dostępne tylko dla elementów DOMText i jemu podobnych
jimmix
Spodobał mi się XPatch używam takiego zapytania:

  1. $elements = $xpath->query('//table/tr/td/p');


co poprawnie mi znajduje Cztery i Pięć, pytanie teraz tylko jak mogę ustalić korespondującą z nimi wartość pomiędzy znacznikiem <th>?
Próbowałem zastosować:
  1. $element->parent_node
lub
  1. $element->parentNode
ale nic nie zwracają a w jej miejsce
  1. $element->nodeName
wyrzuca znacznik <p>

Generalnie chodzi o przetworzenie źródła:

  1. <tr>
  2. <th>
  3. Jeden
  4. </th>
  5. <td>
  6. Dwa
  7. <td>
  8. </tr>
  9. <tr>
  10. <th>
  11. Trzy
  12. </th>
  13. <td>
  14. <p>Cztery</p><p>Piec</p>
  15. <td>
  16. </tr>
  17. </table>


Na wynik:

  1. Jeden: Dwa
  2. Trzy: Cztery
  3. Trzy: Pięć


lub jeśli tak się nieda to może tak:

  1. tr/th: Jeden
  2. tr/td: Dwa
  3. tr/th: Trzy
  4. tr/td: <p>Cztery</p><p>Piec</p>

wówczas, obrobię sobie <p>Cztery</p><p>Piec</p> za pomocą wyrażenia regularnego. Ważne żeby do wartości pomiędzy <td> i <p> można było jednoznacznie przypisać etykietę z <th>
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.