Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]$DOM->getElementsByTagName('tr'); obcina wszystkie znaczniki
Forum PHP.pl > Forum > Przedszkole
php11
Cześć,


chcę przenieść zawartość tabeli html do php by odpowiednio wyświetlić dane.
Poniższy przykład działa prawie dobrze

  1. https://gist.github.com/vihoangson/1d0c4d5b9de97d29d72ee1dda7256f6c


jednak obcina za dużo ;-)

Poza znacznikami tabeli usuwa też znaczniki linków, zdjęcia, które w tej taneli są.
Co zrobić, by tak się nie działo?

Z góry dziekuję za podpowiedzi...
Salvation
Wynika to z dokumentacji: https://www.php.net/manual/en/class.domdocument.php
`nodeValue` zwraca wartość STRING. Jak wiesz, że w znaczniku `td` masz jeszcze inne znaczniki HTML, to użyj po raz kolejny `childNodes`.
php11
Dzięki, powalczę.

Jako uzupełnienie dodam, że potrzebuję uzyskać:

- tablice z zawartością znajdującą się między <tr></tr>
- w której elementami będzie zawartość <td></td>
trueblue
Jeśli jako zawartość rozumiesz kod HTML wewnątrz znacznika <td>, to C14N będzie tym, czego potrzebujesz.
Zakładam, że potrzebujesz tablicy dwuwymiarowej - musisz więc przeiterować po wierszach, w każdym wierszy po kolumnach i wyciągnąć wspomnianą zawartość.
php11
Tak, dokładnie tego chcę, ale schody przede mną...

  1. $html = file_get_contents('tabela.html');
  2. $dom = new DOMDocument;
  3. $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
  4. $xpath = new DOMXPath($dom);
  5. $oddTrs = $xpath->query('//table//tr[position() mod 2=1 and position()>1]');
  6. $oddAAA = $xpath->query('//table//td');
  7.  
  8. $aaa = [];
  9. $bbb = [];
  10. foreach($oddTrs as $key => $tr) {
  11. $zzz = $tr->C14N() . PHP_EOL;
  12.  
  13. if ($td == $key) {
  14. foreach($oddAAA as $td) {
  15. $ccc = $td->C14N();
  16. }
  17. //$aaa[] = $ccc;
  18. }
  19.  
  20. $bbb[] = $ccc;
  21. }
  22. print_r($bbb);
  23. die();
  24.  
trueblue
Dla każdego wiersza musisz pobrać jego <td>. Sprawdź drugi argument metody query w dokumentacji.
Fajnie, że zerkałeś w moje przykłady, ale czy na pewno chodziło Ci o pobranie tylko nieparzystych wierszy? W artykule jest o tym mowa.
php11
Echhhh, pierwszy poziom jakoś odbieram, ale dalej...

  1. $html = file_get_contents('tabela.html');
  2. $dom = new DOMDocument;
  3. $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
  4. $xpath = new DOMXPath($dom);
  5. $wiersze = $xpath->query('//table//tr');
  6. $zzz = [];
  7. foreach($wiersze as $key => $tr) {
  8.  
  9. $zzz[] = $tr->C14N() . PHP_EOL;
  10. $zzz = str_replace('&#haha.gif;', '', $zzz);
  11.  
  12. }
  13. print_r($zzz);
  14. die();
  15.  
trueblue
Tak jak pisałem, dla każdego wiersza powinieneś pobrać jego <td> metodą query.
php11
Tak, wiem, próbuję to od wczoraj zrobić ...

Dzięki za cierpliwość :-)


Edycja--------------------


Ponieważ nie dałem rady, wykombinowałem coś takiego:

1. Usunąlem zbędne znaki

  1. foreach($wiersze as $key => $tr) {
  2. $zzz[] = $tr->C14N() . PHP_EOL;
  3. $zzz = str_replace('&#haha.gif;', '', $zzz);
  4. $zzz = str_replace('<tr>', '', $zzz);
  5. $zzz = str_replace('</tr>', '', $zzz);
  6. $zzz = str_replace('<td>', '', $zzz);
  7. $zzz = str_replace('</td>', ',', $zzz);
  8. }


2. Uworzyłem tablicę w wierszach
  1. $uuu = [];
  2. foreach($zzz as $key => $td) {
  3. $uuu[] = $td = explode(',', $td);
  4. }


3. I chyba mam to, co chciałem do dalszej obróbki...
  1. foreach($uuu as $key => $final) {
  2. echo $final[0] .'---'. $final[1] .'---'. $final[2] .'<br />';
  3. }


@trueblue, jeśli możesz podzielić się Twoim kodem to chętnie się czegoś nauczę :-)
Domyślam się, że moja robota "na piechotę" nie jest za bardzo wydajna...
Dzięki!
trueblue
Mój błąd, metoda C14N jest odpowiednikiem outerHTML z JS, bo zwraca również kod aktualnego węzła. Ponadto przekształca kod HTML na zgodny z XML.
Poniższa metoda też nie jest idealna (ma pierwszą wadę z C14N, ale nie zmienia kodu).

  1. <?php
  2. $html='<table><tr><td>1</td><td><a href="#">2</a></td></tr><tr><td>3</td><td>4</td></tr></table>';
  3. $dom = new DOMDocument;
  4. $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
  5. $xpath = new DOMXPath($dom);
  6.  
  7. $trs = $xpath->query('//table/tr');
  8. $tabela = [];
  9.  
  10. foreach($trs as $key1 => $tr) {
  11. $tabela[$key1]=[];
  12.  
  13. $tds = $xpath->query('.//td', $tr);
  14.  
  15. foreach($tds as $key2 => $td) {
  16. $tabela[$key1][$key2]=substr(substr($td->ownerDocument->saveHTML($td),4),0,-5);
  17. }
  18. }
  19. print_r($tabela);
  20. ?>
php11
Dzięki!


Jednak nie mogę dojść, dlaczego znaczniki </td> nie są zawsze tak samo obcinane:

https://prnt.sc/I7T7y8Imv5yQ
trueblue
A jak wygląda HTML?
php11
Dokładnie ten z Twojego postu powyżej
trueblue
Zmień na:
  1. $tabela[$key1][$key2]=substr(substr(trim($td->ownerDocument->saveHTML($td)),4),0,-5);

Nie wnikam dlaczego, ale jest różnica w tym co zwraca PHP <=7.2 (źle) a PHP >=7.3 (dobrze). W problematycznym przypadku pojawiają się czasem \n na końcach "wyciągniętej" zawartości <td>.

P.S. Albo trim(... , "\n\r\t\v\x00") gdybyś jednak nie chciał tracić spacji wiodących i kończących.
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.