Parser en PHP de gros fichiers XML
En PHP 7
, plusieurs méthodes existent pour parser des xml. SimpleXML
est très pratique
et facile d'accès mais consomme énormement de mémoire avec des gros fichiers. Voyons comment être plus robuste avec l'api XMLReader
qui ne charge pas tout le fichier source en mémoire mais traite les données sous forme de flux.
Prenons la structure de xml suivante:
1<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
2<pdv_liste>
3 <pdv id="1000001" cp="01000" pop="R">
4 <prix nom="Gazole" id="1" maj="2019-01-04T10:53:48" valeur="1328"/>
5 <prix nom="Gazole" id="1" maj="2019-01-07T10:25:25" valeur="1348"/>
6 </pdv>
7 <pdv id="1000002" latitude="4621842" longitude="522767" cp="01000" pop="R">
8 <prix nom="Gazole" id="1" maj="2019-01-03T13:12:46" valeur="1344"/>
9 <prix nom="Gazole" id="1" maj="2019-01-04T14:47:58" valeur="1344"/>
10 </pdv>
11</pdv_liste>
L'exemple réel est tiré de https://donnees.roulez-eco.fr/opendata/annee/2019
dont le fichier xml fait 300Mo, comporte 13000 noeuds <pdv>
et 4 millions de noeuds <prix>
Utilisation de SimpleXML
seul :
1#!/usr/bin/env php
2<?php
3
4$bigXmlFile = 'PrixCarburants_annuel_2019.xml';
5
6$xmlRoot = simplexml_load_file($bigXmlFile);
7foreach ($xmlRoot as $pdvNode) {
8 foreach ($pdvNode->prix as $prix) {
9 echo (float) $prix['valeur'] . "\n";
10 }
11}
Le script va planter si trop peu de mémoire est alloué.
Utilisation avec XmlReader
et SimpleXML
:
1#!/usr/bin/env php
2<?php
3
4$bigXmlFile = 'PrixCarburants_annuel_2019.xml';
5
6$bigXmlReader = new XMLReader();
7$bigXmlReader->open($bigXmlFile);
8while ($bigXmlReader->read()) {
9 if ($bigXmlReader->name === 'pdv') {
10 $subXmlStr = $bigXmlReader->readOuterXml();
11 $pdvNode = simplexml_load_string($subXmlStr);
12 foreach ($pdvNode->prix as $prix) {
13 echo (float) $prix['valeur'] . "\n";
14 }
15 }
16}
17$bigXmlReader->close();
Le script ne va pas aller plus vite mais ne consommera que très peu de mémoire.
comments powered by Disqus