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:
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:
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:
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:
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 :ccool::cry::calim2: