Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [XML] Problem z parsowaniem dużych plików
Forum PHP.pl > Forum > PHP
Sajrox
Witam,

Szukałem szukałem i nie znalazłem nic na ten temat.

Problem wygląda następująco. Mam pewien system który za pomocą xml_parser()" title="Zobacz w manualu PHP" target="_manual parsuje pliki xml z danymi.

Cały kod:
  1. <?php
  2. $this->parser = xml_parser_create("UTF-8");
  3.        xml_set_object($this->parser, $this);
  4.        xml_set_element_handler($this->parser, 'startXML', 'endXML');
  5.        xml_set_character_data_handler($this->parser, 'charXML');
  6.        
  7.        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
  8.        xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
  9.        xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE,1);
  10.  
  11.        if (!($fp = @fopen($this->url, 'rb'))) {
  12.            $this->error("Cannot open {$this->url}");
  13.        }
  14.    
  15.        $endLine = false;
  16.        while (!feof($fp))                                                                                
  17.        {
  18.            $line = '';
  19.            
  20.            for ($i=0; $i<20; $i++)
  21.            {
  22.                $line .= fgets($fp);
  23.                if (feof($fp)) {
  24.                    $endLine = true;
  25.                    break 1;
  26.                }
  27.            }
  28.    
  29.            if (!xml_parse($this->parser, trim($line), feof($fp)))
  30.            {
  31.                echo '<pre>'.$line.'</pre>';
  32.                $this->error(sprintf('XML error at line %d column %d',
  33.                xml_get_current_line_number($this->parser),
  34.                xml_get_current_column_number($this->parser)), $line);
  35.            }  
  36. }
  37. ?>



Przy małych plikach np 2,3,5 mb (1000-3000 linii) wszystko wygląda dobrze, jednak w przypadku gdy plik ma np 100 mb. (100 000 linii) Albo pobiera tylko część np pierwsze 100 linii, albo po prostu nie uruchamia się i wyświetla się biały ekran.

Oczywiście podanie na początku
  1. <?php
  2. ini_set('memory_limit', '64M');
  3. ?>


nic nie daje. Czy metoda xml_parser() posiada jakieś ograniczenia. Co może być przyczyną tego nie mogę parsować dużych plików ?
batman
Zawsze jak miałem parsować duże pliki XML (kilkadziesiąt MB i więcej), korzystałem z XMLReader. Nigdy mnie nie zawiodło.
GrayHat
Ja ostatnio parsowałem XML`a o wielkości 200mb winksmiley.jpg simplexml tutaj nie ma sobie rownych smile.gif szybciutko i bez problemu. Kod:

  1. <?php
  2. $file = '../xml/keywords.xml';
  3.  
  4. $xml = simplexml_load_file($file);
  5.  
  6. foreach($xml->keywords->item AS $item){
  7.    $data = array (
  8.        'id'        =>    (int)$item->attributes()->id,
  9.        'keyword'    =>    (string)$item->attributes()->keyword
  10.    );
  11.    $db->insert('keywords',$data);
  12.    echo ".";
  13. }
  14. ?>


pozdrawiam smile.gif
Sajrox
No właśnie to są bardzo fajne rozwiązania , ale co kiedy serwer ich nie obsługuje sad.gif I tutaj jestem skazany na xml_parse()
GrayHat
Cytat(Sajrox @ 17.12.2008, 19:48:06 ) *
No właśnie to są bardzo fajne rozwiązania , ale co kiedy serwer ich nie obsługuje sad.gif I tutaj jestem skazany na xml_parse()


popros dostawce o doinstalowanie pakietu winksmiley.jpg
simplexml jest wrecz domyslnym pakietem! jezeli w twoim hostingu go nie ma i dostawca nie chce go dograc - zmien hosting!

polecam smile.gif
batman
Nie znam xml_parse więc nie wiem, czy są jakieś ograniczenia na ilość danych. Jedyna klasa jaką znam do XML, która się nie wyłoży przy dużym pliku to właśnie XMLReader. Wszystkie inne rozwiązania (w tym SimpleXML) wywalały się. Jeśli nie masz możliwości skorzystać z dobrodziejstw tej klasy, to będziesz musiał podzielić plik XML na kilka mniejszych.
Sajrox
Cytat(GrayHat @ 17.12.2008, 19:51:07 ) *
popros dostawce o doinstalowanie pakietu winksmiley.jpg
simplexml jest wrecz domyslnym pakietem! jezeli w twoim hostingu go nie ma i dostawca nie chce go dograc - zmien hosting!

polecam smile.gif


Dobry pomysł winksmiley.jpg hehe


Poczytałem troche o XMLReader jak podał batman i powiem że metoda jest genialna ! Może uda mi się przekonać dostawcę o jej uruchomienie.

Dzięki Panowie ! smile.gif
sf
Rozwiązanie z xml_parse jest banalnie proste. Wystarczy wgrywać xml po kawałku. Czyli robisz pętlę while($xml =fread($fp, 1024)) ...
Sajrox
Trochę odświeżę temat smile.gif

Aco w sytuacji gdy parsowanie zostanie przerwane w połowie? W tej chwili próbuję z fseek() oraz ftell()
Jednak gdy zaczynam parsować plik od połowy parser się wysypuje.

Próbowałem dodać przy starcie parsowana od półowy pliku:
Kod
<?xml version="1.0" encoding="ISO-8859-2"?>


Jednak nic to nie dało :/

xml_parse() wywała błąd sad.gif
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.