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

XML/XSL et SOAP Discussion :

Parcours XML à plusieurs niveaux PHP Xmlreader SimpleXMLElement


Sujet :

XML/XSL et SOAP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Par défaut Parcours XML à plusieurs niveaux PHP Xmlreader SimpleXMLElement
    Bonjour,

    Je me tourne vers vous car j'ai un GROS problème dans l'analyse de fichier XML.

    J'utilise XmlReader via PHP avec SimpleXMLElement car les fichiers que j'analyse sont important (supérieur à 1gb).

    Jusqu'à maintenant l'analyse de flux ne me posait pas problème.

    Voici la méthode utilisée pour un flux classique en exemple, le noeud station uniquement m'intéresse. Dans cette méthode j'arrête au dernier noeud station :

    Flux XML simple sur un niveau
    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
    <?xml version="1.0"?>
    <offres>
     <catalogue id="226"  site="france" >
     <stations>
       <station>
        <identifiant>
         <![CDATA[11]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[12]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[13]]>
        </identifiant>
        </station>
       </stations>
    </catalogue></offres>

    Code PHP permettant l'ouverture et l'analyse du fichier
    Code php : 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
    <?php
    $reader = new XMLReader();
    $reader->open('test.xml');
     
    $doc = new DOMDocument;
     
    while ($reader->read() && $reader->name !== 'station');
     
    while($reader->name === 'station')
    {
     $node = new SimpleXMLElement(utf8_encode(html_entity_decode($reader->readOuterXML())));	
     $station_cle = (trim($node->station_cle));
     echo "$station_cle<br/>";	
     $reader->next('station');
    }
    // Je m'arrete bien au dernier noeud station
    }
    ?>



    Je dois dorénavant analyser plusieurs noeuds catalogues à la suite comprenant chacun plusieurs noeuds stations.


    Le code XML exemple pour mieux comprendre donne ceci :

    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
    <?xml version="1.0"?>
    <offres>
     <catalogue id="226"  site="france" >
     <stations>
       <station>
        <identifiant>
         <![CDATA[11]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[12]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[13]]>
        </identifiant>
        </station>
       </stations>
    </catalogue>
    <catalogue id="227"  site="france" >
     <stations>
       <station>
        <identifiant>
         <![CDATA[11]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[12]]>
        </identifiant>
        </station>
        <station>
        <identifiant>
         <![CDATA[13]]>
        </identifiant>
        </station>
       </stations>
    </catalogue>
    </offres>

    Mon problème : avec le code d'analyse ci-dessus je ne parviens pas à passer aux catalogues suivant je reste dans le premier catalogue.. mon action se termine au dernier noeud station

    Comment faire pour passer au second catalogue ?

    J'ai essayé d'imbriquer cette boucle mais impossible de passer dans le second catalogue.

    Code php : 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
    <?php
    while ($reader->read() && $reader->name !== 'offres');
     
    while($reader->name === 'offres')
    {
        while ($reader->read() && $reader->name !== 'catalogue');
        while($reader->name === 'catalogue')
        {
     
            while ($reader->read() && $reader->name !== 'station');
            while($reader->name === 'station')
            {
              $node = new SimpleXMLElement(utf8_encode(html_entity_decode($reader->readOuterXML())));	 
              $reader->next('station');
            }
        $reader->next('catalogue');
        }
    }

    1. J'ai bien tenté un foreach ou un simple for en calculant le nombre d'élément du tableau mais ce nombre peut être très important.. le but est de charger au fur et à mesure sans consommer trop de mémoire..

    2. Le problème vient-il du fait que je me réfère à chaque fois à reader de base ? Faut-il créer un nouveau reader à la suite ? Comme par exemple $reader_catalogue puis $reader_station ?

    Merci d'avance pour votre aide !

    Gloire à celui qui trouvera

  2. #2
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    Logiquement plus simple et plus de clarté et le résultat comme attendu, quoiqu'il puisse être racourci peut-être un peu.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    while ($reader->read()) {
        if (($reader->nodeType==XMLReader::ELEMENT) && ($reader->name=='catalogue')) {
            //faire quelque chose envers chaque catalogue si besoin
            while($reader->read()) {
                if (($reader->nodeType==XMLReader::ELEMENT) && ($reader->name=='station')) {
                    $node = new SimpleXMLElement(utf8_encode(html_entity_decode($reader->readOuterXML())));	
                    //$station_cle = (trim($node->station_cle));    //je ne sais pas quoi
                    $station_cle = (trim($node->identifiant));
                    echo "$station_cle<br/>";
                    //faire des choses avec $node si besoin
                }
            }
        }
    }

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Par défaut
    Bonjour, merci pour le retour !!

    Je viens d'effectuer un premier test et à priori cela n'a pas fonctionné car je continuais d'utiliser next('station') du coup plantage et impossible de passer au catalogue suivant.

    J'ai retiré next('station'); comme dans ton exemple et cela semble fonctionner sur un petit fichier.. je vais lancer un test sur mon fichier supérieur à 1gb mais si ça marche maintenant...

    Je reviens tout l'heure pour valider si ça a fonctionné..

    Merci


  4. #4
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    D'abord, ceci: pourquoi faut-il read() deux fois pour sortir la valeur ->value?
    $station_cle = "";
    $reader->read(); $reader->read();
    $station_cle = mysql_real_escape_string(trim($reader->value));
    // echo "station $station_cle <br/>";
    Je m'en doute grandement sans voir le document xml.

    Et puis,
    Mon problème actuel, le fichier complet n'est pas lu complètement.. le fichier pèse 1,6gb.
    Si vous aviez le doute que le problème provenait de l'importance du document, méfiez vous. XMLReader doit être capable de le tirer même à un moment donné, vous passez à SimpleXML pour une sous-aborescence que sa taille n'est comparablement beaucoup moins que le document originel. Si ça eventuellement pose problème, vous pouvez toujours vous placer algorithmiquement dedans le cadre de XMLReader.

    La raison qu'il s'ârret quelque part doit être envisagée. Le document pouvait mal-formée pour des raisons multiples, etc. Pour faire voir, lire un peu sur la configuration track_errors dans php.ini. Il est par défaut off. Changez là on.
    Et puis dans le code, vous devriez controler la variable $php_errormsg quelque peu comme ça.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(isset($php_errormsg)) {
        echo "<div>error message: ", $php_errormsg,"</div>\n";
    }
    Faites voir si ça aide?

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Par défaut
    Merci pour ton retour.

    Je n'ai pas pris le temps de répondre avant..

    Sujet résolu !!

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/05/2011, 00h23
  2. [Flex4] Dataprovider issu de XML à plusieurs niveaux de noeuds
    Par Imadus dans le forum Flex
    Réponses: 4
    Dernier message: 29/11/2010, 17h14
  3. Réponses: 3
    Dernier message: 20/08/2008, 10h24
  4. [JDOM] Fichier XML à plusieurs niveaux
    Par sidneyvba dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 06/11/2007, 15h58
  5. Réponses: 3
    Dernier message: 30/08/2006, 16h39

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