IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques et frameworks PHP Discussion :

[SimpleXML] Erreur LibXml "Extra content at the end of the document" malgré XML valide


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10
    Points : 6
    Points
    6
    Par défaut [SimpleXML] Erreur LibXml "Extra content at the end of the document" malgré XML valide
    Hello,

    Je traite des fichiers XML volumineux (10 fichiers qui vont de quelques 100aines de Ko à plus de 350Mo par ficher).
    Quand je traite les fichiers unitairement, aucun souci avec simplexml_load_file (i.e. mes fichiers XML sont valides).
    Quand je traite les fichiers à la chaine (script qui lit mon dossier, et traite les fichiers les uns après les autres), j'ai un bug: si jamais 2 fichiers volumineux sont traités l'un après l'autre, le 1er est traité mais quand le script passe au fichier suivant je catch une LibXmlError#186 (Extra content at the end of the document).
    Si je nomme mes fichiers de manière à ce que mon script ne traite jamais 2 fichiers très volumineux l'un après l'autre, je n'ai pas de soucis.
    Le truc c'est que j'aimerais ne pas avoir à bricoler une alternance de "fichier volumineux/fichier léger/fichier volumineux/fichier léger/etc" car c'est sale et naze.
    J'ai testé en passant le paramètre LIBXML_PARSEHUGE à mon simplexml_load_file mais rien n'y fait...
    Sauriez-vous comment régler ce problème svp?

    Ci dessous le code de ma commande php qui traite les fichiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    class GenresRetriever {
     
        public static function RetrieveGenres($pCatalogsDir, $pReportFile)
        {
            if(gc_enabled() == false)
                gc_enable();
     
            libxml_use_internal_errors(true);
            $genres = array();
            //Directory ou sont stockés mes fichiers xml à traiter
            $d = dir($pCatalogsDir);
     
            while($entry = $d->read())
            {
                if($entry != '.' && $entry != '..')
                {
                    $xml = simplexml_load_file($pCatalogsDir.$entry, 'SimpleXMLElement', LIBXML_PARSEHUGE);
                    if(!libxml_get_last_error())
                    {
                        $products = $xml->Product;
                        /******************************* */
                        /* BEGINNING OF PRODUCTS PARSING */
                        /******************************* */
                        foreach ($products as $product)
                        {
                            /********************* */
                            /* Book's ID retrieval */
                            /********************* */
                            $productIdMarkups = $product->ProductIdentifier;
                            $ids = array('bookPublisherId' => '',
                                        'GTIN13' => '',
                                        'ISBN13' => '');
     
                            if ($productIdMarkups != '') {
                                foreach ($productIdMarkups as $productIdMarkup) {
                                    switch (intval($productIdMarkup->ProductIDType)) {
                                        case 1 :
                                            $ids['bookPublisherId'] = (string) $productIdMarkup->IDValue;
                                            break;
     
                                        case 3 :
                                            $ids['ISBN13'] = (string) $productIdMarkup->IDValue;
                                            break;
     
                                        case 15 :
                                            $ids['ISBN13'] = (string) $productIdMarkup->IDValue;
                                            break;
     
                                        default : $ids['ISBN13'] = time()+rand(1, 1000);
                                            break;
                                    }
                                }
                            }
     
                            /******************************* */
                            /* Publisher and ID verification */
                            /******************************* */
                            $descriptiveDetailMarkup = $product->DescriptiveDetail;
                            if($product->PublishingDetail->Publisher=='')
                                continue;
     
                            $subjectMarkups = $descriptiveDetailMarkup->Subject;
                            if ($subjectMarkups != '') {
                                foreach ($subjectMarkups as $subjectMarkup) {
                                    $subjectSchemeMarkup = $subjectMarkup->SubjectSchemeIdentifier;
                                    switch (intval($subjectSchemeMarkup)) {
                                        case 29:
                                            $genresTemp = self::parseGenres((string) self::cleanSpecialChars($subjectMarkup->SubjectHeadingText));
                                            foreach($genresTemp as $g)
                                            {
                                                if(array_key_exists($g, $genres) == false)
                                                {
                                                    $genres[$g]['genre'] = $g;
                                                    $genres[$g]['nb'] = 1;
                                                }
                                                else
                                                {
                                                    $genres[$g]['nb']++;
                                                }
                                            }
                                            break;
     
                                        default:
                                            break;
                                    }
                                }
                            }
                        }
                        echo 'File '.$entry.' processed'."\r\n";
                    }
                    else
                    {
                        echo "ERROR:\r\n";
                        var_dump(libxml_get_last_error());
                        libxml_clear_errors();
                    }
                    $xml = null;
                    $products = null;
                    gc_collect_cycles();
                }
            }
            $d->close();
     
            $fp = fopen($pReportFile, 'w');
            foreach($genres as $genre)
            {
                fwrite($fp, $genre['genre'].'|'.$genre['nb']."\r\n");
            }
            fclose($fp);
     
            return;
        }

  2. #2
    Membre émérite
    Avatar de gene69
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 769
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 769
    Points : 2 446
    Points
    2 446
    Par défaut
    est ce que tu peux refiler un fichié dont les informations aurait été neutralisée pour voir si on peut reproduire sur nos plateformes?



    la seule chose qui me viens à l'esprit en lisant le code c'est que la partie du code commançant à la ligne 21 serait bien mieux dans une methode independante parce que ça te séparerait le traitement de la donnée et le chargement de celle-ci.

    est-ce que tu as la même erreur si tu découpes le simplexml_load_file en file_get_contents() + simplexml_ load_ string ?

    je suppose que tu as aussi contrôlé le charset de tes fichiers!
    PHP fait nativement la validation d'adresse électronique .
    Celui qui a inventé mysql_connect(...) or die() est déjà mort plusieurs fois.

    Utilisez le bouton résolu!

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    En PJ un exemple de fichier pour que tu vois la structure de la bête
    Alors les fichiers sont encodés en UTF-8 (balise d'en-tête: <?xml version="1.0" encoding="UTF-8"?>)
    Pour le file_get_contents, il crash dès le traitement du 1er fichier (qui est celui de 350Mo..)
    Allowed memory size of 536870912 bytes exhausted (tried to allocate 244463179 bytes) in .... (ligne avec mon file_get_contents)
    Le truc avec simplexml_load_file c'est que j'ai l'impression qu'il ya une limitation sur l'enchainement de 2 gros fichiers, comme si cela lui faisait péter un câble.
    Car unitairement il traite bien les fichiers, et même les uns après les autres si je n'ai pas 2 gros fichiers qui se suivent.

    PS: pour la mise en fonction yep je vais faire ça, afin de clarifier le code
    Fichiers attachés Fichiers attachés

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Well well... j'ai isolé le traitement des fichiers dans une fonction comme tu me l'avais suggéré, et j'ai passé ma classe de static à non static. Eh bien tout fonctionne à présent... mon script traite tous les fichiers sans broncher!
    Je ne sais pas exactement pourquoi ça fonctionne maintenant, est-ce que le côté static des choses alourdissait le traitement / mélangeait les pinceaux du script??

    Pour info voici le script modifié:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
     
        public function RetrieveGenres($pCatalogsDir, $pReportFile)
        {
            if(gc_enabled() == false)
                gc_enable();
     
            libxml_use_internal_errors(true);
            $genres = array();
            $d = dir($pCatalogsDir);
            while($entry = $d->read())
            {
                $this->processFile($entry, $pCatalogsDir, $genres);
            }
            $d->close();
     
            $fp = fopen($pReportFile, 'w');
            foreach($genres as $genre)
                fwrite($fp, $genre['genre'].'|'.$genre['nb']."\r\n");
            fclose($fp);
     
            return;
        }
     
        private function processFile($pEntry, $pCatalogsDir, &$pGenres)
        {
            if($pEntry != '.' && $pEntry != '..')
            {
                $xml = simplexml_load_file($pCatalogsDir.$pEntry, 'SimpleXMLElement', LIBXML_PARSEHUGE);
                if(!libxml_get_last_error())
                {
                    $products = $xml->Product;
                    /******************************* */
                    /* BEGINNING OF PRODUCTS PARSING */
                    /******************************* */
                    foreach ($products as $product)
                    {
                        /********************* */
                        /* Book's ID retrieval */
                        /********************* */
                        $productIdMarkups = $product->ProductIdentifier;
                        $ids = array('bookPublisherId' => '',
                                    'GTIN13' => '',
                                    'ISBN13' => '');
     
                        if ($productIdMarkups != '') {
                            foreach ($productIdMarkups as $productIdMarkup) {
                                switch (intval($productIdMarkup->ProductIDType)) {
                                    case 1 :
                                        $ids['bookPublisherId'] = (string) $productIdMarkup->IDValue;
                                        break;
     
                                    case 3 :
                                        $ids['ISBN13'] = (string) $productIdMarkup->IDValue;
                                        break;
     
                                    case 15 :
                                        $ids['ISBN13'] = (string) $productIdMarkup->IDValue;
                                        break;
     
                                    default : $ids['ISBN13'] = time()+rand(1, 1000);
                                        break;
                                }
                            }
                        }
     
                        /******************************* */
                        /* Publisher and ID verification */
                        /******************************* */
                        $descriptiveDetailMarkup = $product->DescriptiveDetail;
                        if($product->PublishingDetail->Publisher=='')
                            continue;
     
                        $subjectMarkups = $descriptiveDetailMarkup->Subject;
                        if ($subjectMarkups != '') {
                            foreach ($subjectMarkups as $subjectMarkup) {
                                $subjectSchemeMarkup = $subjectMarkup->SubjectSchemeIdentifier;
                                switch (intval($subjectSchemeMarkup)) {
                                    case 29:
                                        $genresTemp = $this->parseGenres((string) $this->cleanSpecialChars($subjectMarkup->SubjectHeadingText));
                                        foreach($genresTemp as $g)
                                        {
                                            if(array_key_exists($g, $pGenres) == false)
                                            {
                                                $pGenres[$g]['genre'] = $g;
                                                $pGenres[$g]['nb'] = 1;
                                            }
                                            else
                                            {
                                                $pGenres[$g]['nb']++;
                                            }
                                        }
                                        break;
     
                                    default:
                                        break;
                                }
                            }
                        }
                    }
                    echo 'File '.$pEntry.' processed'."\r\n";
                }
                else
                {
                    echo "ERROR:\r\n";
                    var_dump(libxml_get_last_error());
                    libxml_clear_errors();
                }
                $xml = null;
                $products = null;
                gc_collect_cycles();
            }
        }
    Merci pour la piste que tu m'as fourni, cela m'a permis de résoudre le problème!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 27/03/2013, 16h59
  2. [XML] simplexml erreur "extra content"
    Par gwena54 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 24/02/2010, 15h45
  3. [SimpleXML] Erreur "failed to load external entity"
    Par seb92500 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 04/02/2007, 09h27
  4. postgres-php erreur unterminated quoted
    Par peppena dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 02/05/2006, 16h24
  5. Réponses: 4
    Dernier message: 29/09/2004, 09h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo