Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V  < 1 2  
Reply to this topicStart new topic
> [xml][DOM] sama podstawa
marcinek37
post 11.04.2013, 23:01:47
Post #21





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


troszkę ciekawych informacji z tego linka wyciągnąłem, bardzo Ci dziękuję - ponownie wink.gif

powstał u mnie kolejny problem:
  1. <?
  2. $dom = new DOMDocument('1.0', 'utf-8');
  3. $dom->formatOutput = true;
  4. $products_list = $dom->appendChild($dom->createElement('products_list'));
  5. $product = $products_list->appendChild($dom->createElement('product'));
  6. $product->appendChild($dom->createElement('id', 1));
  7. $product->appendChild($dom->createElement('name', '<b>AAA</b>'));
  8. $dom->save('nazwa.xml');
  9. ?>


jak widzisz, tworzę już swoje pliki xml (progress jest), jednak element <name> ma zamieniane znaczniki HTML w np. &lt;b&gt;.

całość wygenerowanego pliku wygląda tak:
<?xml version="1.0" encoding="utf-8"?>
<products_list>
<product>
<id>1</id>
<name>&lt;b&gt;AAA&lt;/b&gt;</name>
</product>
</products_list>

a powinna tak:
<?xml version="1.0" encoding="utf-8"?>
<products_list>
<product>
<id>1</id>
<name><b>AAA</b></name>
</product>
</products_list>
Go to the top of the page
+Quote Post
zegarek84
post 11.04.2013, 23:21:19
Post #22





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


Cytat(marcinek37 @ 12.04.2013, 00:01:47 ) *
jak widzisz, tworzę już swoje pliki xml (progress jest), jednak element <name> ma zamieniane znaczniki HTML w np. <b>

nadeszła chwila relaksu, a że nie jestem programistą z zawodu to nie znam funkcji na pamięć więc pewnie wkradną się błędy lub możesz nie bardzo zrozumieć to co piszę skoro jestem pod wpływem ;p

no właśnie to poprawne działanie - w JavaScript podobny fragment kody wykorzystuje się do implementacji funkcji typu escapeHTML encodeHTML gdzie na odpowiednie znaczniki zamienia się znaki typu <> itd... by np. wyświetlić potem kod HTML... pod tym kontem spojrzyj, to nie będziesz widział błędu ;]

rozwiązanie na szybko jak jestem pod wpływem - luknij która funkcja zamienia tak na encje w manualu php i są jej odpowiedniki do dekodowania - więc w XML'u możesz przechowywać strukturę zakodowaną - co w sumie było by poprawne, gdyż nie przewidywałeś tam dodatkowych elementów drzewa XML (nie patrz na kod HTML ;p) - ps. jeśli jest tam możliwość niepoprawnej struktury XML to niech lepiej to zostanie zakodowane by nie rozwaliło Ci pliku XML (analogia do HTML iniection)...

drugie rozwiązanie na szybko jak jestem pod wpływem przypomina tą funkcję którą robiłeś z innerHTML - po prostu pokombinuj, jak zaimportować już Elementy a nie tekst ;] - jak sam poprubujesz to nawet jak nie dasz rady prędzej to zapamiętasz... daj kod co tam zrobiłeś, jak będę miał czas to może poprawię ;] - ale nie nastawiaj się, że będę miał czas gdyż mam swoje zajęcia jutro (już dziś ;p) w sobotę też a w niedzielę rodzinkę pasuje odwiedzić ;p

pozdro...

Ten post edytował zegarek84 11.04.2013, 23:24:07


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
marcinek37
post 12.04.2013, 01:04:14
Post #23





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


1. wydaje się, że to ta metoda: createElement przerabia kod HTML na encje
a nie ma ona żadnych dodatkowych parametrów... zrobiłem to łopatologicznie - wygenerowałem plik, a potem go przerobiłem innym skryptem - innego rozwiązania chyba nie znajdziemy

2. postanowiłem wgłębić się w DOM, dla przykładu chcę wykonać listę linków znajdujących się na onecie
  1. <?
  2. $objDOM = new DOMDocument();
  3. $objDOM->load("http://www.onet.pl");
  4. ?>


no i pokazała się ogromna lista błędów - czyja to wina? skryptu czy onetu?

Ten post edytował marcinek37 12.04.2013, 01:29:44
Go to the top of the page
+Quote Post
zegarek84
post 12.04.2013, 11:51:23
Post #24





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


HTML nie zawsze jest poprawnym dokumentem XML ;] - więc ze stronami niemal zawsze będzie podobnie... mając tego świadomość możesz wyłączyć wyświetlanie błędów przy tej funkcji
@$objDOM->load("http://www.onet.pl");

kod strony zapisanej z obiektu DOM może trochę odbiegać od źródeł... gdy będziesz więcej programował i poznawał inne języki to polecam korzystanie z silnika przeglądarki np. WebKit w Fremworku Qt (ale to już język C++)...

na razie nie przejmuj się tymi błędami... jednak możesz mieć problemy z kodowaniem niektórych stron - czytaj dokumentację i komentarze jak sobie z tym poradzić ;] - dasz radę...

wszystkie linki w wyr. xpath nie ważne gdzie się znajdują to po prostu "//a", z kolei wewnątrz jakiegoś obiektu o określonym id nie bezpośrednie dzieci to "//*[@id="cos_tam"]//a" - zwracaj uwagę kiedy np. stosować "//" a kiedy "/", ale to już chyba doczytałeś... i podobnie jak przykłady wyżej jeśli szukasz xpath względem jakiegoś elementu to zaczynaj wyrażenie od "./"

ps. względem wyr. CSS "//" odpowiada spacji " " a "/" odpowiada ">"

Cytat(marcinek37 @ 12.04.2013, 02:04:14 ) *
1. wydaje się, że to ta metoda: createElement przerabia kod HTML na encje
a nie ma ona żadnych dodatkowych parametrów... zrobiłem to łopatologicznie - wygenerowałem plik, a potem go przerobiłem innym skryptem - innego rozwiązania chyba nie znajdziemy

  1. <?php
  2. error_reporting(E_ALL|E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $oDom = new DOMDocument('1.0', 'utf-8');
  6. $oDom->formatOutput = true;
  7. $oProductList = $oDom->appendChild($oDom->createElement('products_list'));
  8. $oProduct = $oProductList->appendChild($oDom->createElement('product'));
  9. $oProduct->appendChild($oDom->createElement('id', 1));
  10. $oName = $oProduct->appendChild($oDom->createElement('name')); /* @var $oName DOMNode */
  11. $sName = '<b>AAA';
  12. $oDomTmp = new DOMDocument('1.0', 'utf-8');
  13. // na wszelki wypadek doklejamy body żeby nie tworzyło paragrafów w czystym tekście,
  14. // jeśli wystąpi 2 razy body to zostanie pominięte
  15. @$oDomTmp->loadHTML('<body>'.$sName); // wyciszenie błędów przy niepoprawnych html'ach
  16. $oBody = $oDomTmp->getElementsByTagName('body')->item(0); /* @var $oBody DOMNode */
  17. foreach ($oBody->childNodes as $oEl) { /* @var $oEl DOMNode */
  18. $oName->appendChild($oDom->importNode($oEl, TRUE));
  19. }
  20. echo $oDom->saveXML();

Cytat(marcinek37 @ 12.04.2013, 02:04:14 ) *
2. postanowiłem wgłębić się w DOM, dla przykładu chcę wykonać listę linków znajdujących się na onecie
  1. <?
  2. $objDOM = new DOMDocument();
  3. $objDOM->load("http://www.onet.pl");
  4. ?>

no i pokazała się ogromna lista błędów - czyja to wina? skryptu czy onetu?

  1. <?php
  2. error_reporting(E_ALL|E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $oDOM = new DOMDocument();
  6. @$oDOM->loadHTMLFile("http://www.onet.pl");
  7. $oXPath = new DOMXPath($oDOM);
  8. echo $oXPath->query('//a')->length;


Ten post edytował zegarek84 12.04.2013, 12:14:15


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
marcinek37
post 12.04.2013, 11:56:27
Post #25





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


bardzo dziękuję za informacje

szkoda tylko, że trzeba używaż dwóch modeli: DOM i xpath, ale to chyba da się ogarnąć wink.gif
Go to the top of the page
+Quote Post
zegarek84
post 12.04.2013, 12:16:14
Post #26





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


poprawiłem powyższy kod - xpath nie musisz używać ale problem był, jeśli miałeś np $sName = 'cokolwiek' jako zwykły string np. z bazy - dodawało paragraf to to poprawiłem i będziesz miał poprawne elementy nawet przy nie poprawnym HTML'u - luknij teraz...

Ten post edytował zegarek84 12.04.2013, 12:16:32


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
marcinek37
post 12.04.2013, 15:45:21
Post #27





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


na razie nie chcę korzystać z DOMXPath, a skupić się wyłącznie na DOMDocument
martwi mnie, że ten kod nie pokazuje niczego:
  1. <?
  2. $objDOM = new DOMDocument();
  3. $objDOM->load("http://www.onet.pl");
  4. echo $objDOM->SaveHTML();
  5. ?>


to przez te błędy, czy po prostu bez DOMXPath nic nie zrobię?
Go to the top of the page
+Quote Post
zegarek84
post 12.04.2013, 16:46:21
Post #28





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


przecież napisałem Ci wyżej, iż .load służy do wczytywania plików XML - strona nie ma poprawnego formatu xml miałeś skorzystać z funkcji .loadHTMLFile
  1. <?php
  2. error_reporting(E_ALL|E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $objDOM = new DOMDocument();
  6. @$objDOM->loadHTMLFile("http://www.onet.pl");
  7. echo $objDOM->saveHTML();


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
marcinek37
post 12.04.2013, 17:28:25
Post #29





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


przepraszam, źle odczytałem Twoje wskazówki, jest jeszcze jeden mały kłopot, a mianowicie brak polskich znaków:
  1. <?
  2. error_reporting(E_ALL|E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $objDOM = new DOMDocument('1.0', 'utf-8');
  6. @$objDOM->loadHTMLFile("http://www.onet.pl");
  7. echo mb_convert_encoding($objDOM->SaveHTML(), 'UTF-8', 'HTML-ENTITIES');
  8. ?>


to chyba ostatni problem, bo całą resztę zaczynam ogarniać, w dużej mierze dzięki Tobie wink.gif
Go to the top of the page
+Quote Post
zegarek84
post 12.04.2013, 21:24:10
Post #30





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


nie jestem z zawodu programistą ale dawniej do parsowania gry www właśnie korzystałem z PHP i DOM ^^ - niestety z kodowaniem trzeba wziąć sprawy w swoje ręce... oprócz kodu przeczytaj komentarze w tej funkcji:
DOMDocument::loadHTML
więc plik musiałby albo zawierać na początku dyrektywę kodowania albo trzeba przekonwertować źródło i znaki UTF-8 do encji html... preferuję to drugie podejście...

kodowanie na stronie możesz rozpoznać dwojako, albo z nagłówków odpowiedzi jeśli byś korzystał z CURL'a albo z tagu meta określającego kodowanie... no ale żeby go odczytać to musisz w pierw wczytać dokument jakim jest (chyba, że wolisz bawić się z wyrażeniami regularnymi ale nie polecam) - i to podejście Ci na początku polecam... inne rozwiązanie by zmniejszyć pamięć (choć w sumie nie musisz zwłaszcza w celach ćwiczebnych) to ten tag meta odszukać przez SAX i przerwać przeglądanie dokumentu po znalezieniu kodowania - ale na tym etapie wiedzy jak Ci wspominałem wcześniej nawet tego nie dotykaj ;p

a teraz jak znasz kodowanie strony to możesz zrobić np. w ten sposób:
  1. <?php
  2. error_reporting(E_ALL|E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $objDOM = new DOMDocument('1.0', 'UTF-8');
  6. $sHTML = mb_convert_encoding(file_get_contents("http://www.onet.pl"),'HTML-ENTITIES', 'UTF-8');
  7. @$objDOM->loadHTML($sHTML);
  8. // echo $objDOM->saveHTML();
  9. echo mb_convert_encoding($objDOM->saveHTML(),'UTF-8' ,'HTML-ENTITIES');

w ostatniej linijce nie musisz konwertować z powrotem, ale podejrzewam, iż nie chcesz encji ;]

a jeśli nie znasz kodowania to na Twój aktualny poziom wiedzy można by np. w ten sposób:
  1. <?php
  2. error_reporting(E_ALL | E_STRICT);
  3. ini_set('display_errors', '1');
  4.  
  5. $objDOM = new DOMDocument('1.0', 'UTF-8');
  6. $sHTML = file_get_contents("http://www.onet.pl");
  7. //$sHTML = file_get_contents("http://localhost/modul_1/public/urzytkownik/zarejestrowani/");
  8. @$objDOM->loadHTML($sHTML);
  9. $oXPath = new DOMXPath($objDOM);
  10. $oMeta = $oXPath->query('//meta[@charset]|//meta[@http-equiv and @content]')->item(0);
  11. $oXPath = NULL;
  12. unset($oXPath);
  13. $sEcode = 'UTF-8';
  14. if ($oMeta) {
  15. if ($oMeta->hasAttribute('charset')) {
  16. $sEcode = $oMeta->getAttribute('charset');
  17. }
  18. if ($oMeta->hasAttribute('content')) {
  19. $aTemp = explode('=', $sEcode = $oMeta->getAttribute('content'), 2);
  20. $sEcode = trim($aTemp[1]);
  21. }
  22. }
  23. $sHTML = mb_convert_encoding($sHTML, 'HTML-ENTITIES', $sEcode);
  24. @$objDOM->loadHTML($sHTML);
  25. // przy następnej linijce uważaj gdyż może Ci rozwalić plik html...
  26. echo mb_convert_encoding($objDOM->saveHTML(), 'UTF-8', 'HTML-ENTITIES');


ps.
przypomniałem sobie i może Cię to zainteresować, a raczej powinieneś się zainteresować jeśli zamierzasz parsować strony
luknij na tą rozwijaną bibliotekę:
https://github.com/html5lib/html5lib-php
info o niej pośrednio ze strony:
http://ejohn.org/blog/pure-javascript-html-parser/

Ten post edytował zegarek84 13.04.2013, 00:13:24


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
marcinek37
post 14.04.2013, 23:12:43
Post #31





Grupa: Zarejestrowani
Postów: 239
Pomógł: 0
Dołączył: 2.06.2011

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


przepraszam, że odpisuję Ci dopiero teraz, ale cały weekend byłem poza komputerem...
bardzo, ale to bardzo mi pomogłeś, wszystko jak na razie rozumiem, dziękuję i pozdrawiam wink.gif
Go to the top of the page
+Quote Post

2 Stron V  < 1 2
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: 25.04.2024 - 04:57