Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]$DOM->getElementsByTagName('tr'); obcina wszystkie znaczniki
php11
post 21.10.2022, 18:22:13
Post #1





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


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...

Ten post edytował php11 21.10.2022, 20:13:38
Go to the top of the page
+Quote Post
Salvation
post 21.10.2022, 20:57:31
Post #2





Grupa: Zarejestrowani
Postów: 338
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


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`.
Go to the top of the page
+Quote Post
trueblue
post 21.10.2022, 21:11:57
Post #3





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Jeśli chcesz uzyskać zawartość elementu jako string (coś w rodzaju innerHTML z JS), to użyj metody C14N.

Polecam:
https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e01
https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e03
https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e03
https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e04


--------------------
Go to the top of the page
+Quote Post
php11
post 22.10.2022, 08:16:12
Post #4





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


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>
Go to the top of the page
+Quote Post
trueblue
post 22.10.2022, 08:48:09
Post #5





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


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ść.


--------------------
Go to the top of the page
+Quote Post
php11
post 22.10.2022, 15:39:35
Post #6





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


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.  
Go to the top of the page
+Quote Post
trueblue
post 22.10.2022, 16:52:37
Post #7





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


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.


--------------------
Go to the top of the page
+Quote Post
php11
post 23.10.2022, 11:46:25
Post #8





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


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.  
Go to the top of the page
+Quote Post
trueblue
post 23.10.2022, 12:04:12
Post #9





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Tak jak pisałem, dla każdego wiersza powinieneś pobrać jego <td> metodą query.


--------------------
Go to the top of the page
+Quote Post
php11
post 23.10.2022, 12:39:45
Post #10





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


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!


Ten post edytował php11 23.10.2022, 13:44:34
Go to the top of the page
+Quote Post
trueblue
post 24.10.2022, 09:36:06
Post #11





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


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. ?>


Ten post edytował trueblue 24.10.2022, 09:36:31


--------------------
Go to the top of the page
+Quote Post
php11
post 11.11.2022, 19:11:45
Post #12





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


Dzięki!


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

https://prnt.sc/I7T7y8Imv5yQ

Ten post edytował php11 11.11.2022, 19:12:20
Go to the top of the page
+Quote Post
trueblue
post 11.11.2022, 19:14:25
Post #13





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


A jak wygląda HTML?


--------------------
Go to the top of the page
+Quote Post
php11
post 11.11.2022, 19:18:12
Post #14





Grupa: Zarejestrowani
Postów: 210
Pomógł: 5
Dołączył: 11.02.2011

Ostrzeżenie: (0%)
-----


Dokładnie ten z Twojego postu powyżej
Go to the top of the page
+Quote Post
trueblue
post 11.11.2022, 19:25:02
Post #15





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


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.

Ten post edytował trueblue 11.11.2022, 19:26:44


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.03.2024 - 06:25