Précédent   Forum du club des développeurs et IT Pro > PHP > Bibliothèques et frameworks > XML
XML Forum d'entraide sur XML avec PHP. Exemples : SimpleXML, OpenXML... Avant de poster -> FAQ XML, Cours XML et Sources XML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 23/09/2012, 19h44   #1
Remiguel
Invité de passage
 
Inscription : octobre 2003
Messages : 7
Détails du profil
Informations forums :
Inscription : octobre 2003
Messages : 7
Points : 1
Points : 1
Par défaut PHP Copier seulement les noeuds désirés d'un fichier xml dans un nouveau fichier xml

Bonjours

Le titre est assez descriptif, je crois.

J'ai un gros fichier xml (200 Mo) duquel je veux extraire seulement certains noeuds. Tout ça en PHP.

Mon fichier xml est comme celui-ci (je l'ai réduit pour l'exemple)
Code xml :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="Osmosis 0.39">
  <node id="21405637" version="5" timestamp="2011-11-08T09:36:26Z" uid="422863" user="Virgílio" changeset="9771590" lat="32.8232559" lon="-17.1026471">
    <tag k="source" v="PGS"/>
    <tag k="sport" v="swimming"/>
  </node>
  <node id="21410164" version="8" timestamp="2012-01-07T21:35:36Z" uid="61942" user="SomeoneElse" changeset="10326005" lat="32.7348317" lon="-17.2082492">
    <tag k="leisure" v="slipway"/>
    <tag k="source" v="PGS"/>
  </node>
  <node id="24984214" version="3" timestamp="2008-04-16T20:04:24Z" uid="8204" user="oha" changeset="162913" lat="38.6099096" lon="-9.1015325">
    <tag k="name" v="Fogueteiro"/>
    <tag k="railway" v="station"/>
  </node>
  <node id="25414227" version="4" timestamp="2009-02-28T21:08:53Z" uid="39787" user="jakomo" changeset="701481" lat="38.7457767" lon="-9.1354754">
    <tag k="name" v="Roma - Areeiro"/>
    <tag k="railway" v="station"/>
  </node>
  <node id="1638129315" version="1" timestamp="2012-02-18T20:05:56Z" uid="32168" user="Fernandinand" changeset="10723860" lat="40.1147978" lon="-8.5139013">
    <tag k="emergency" v="fire_hydrant"/>
    <tag k="fire_hydrant:position" v="sidewalk"/>
    <tag k="fire_hydrant:type" v="pillar"/>
  </node>
</osm>

Je lis mon fichier avec xmlreader et j'utilise épand pour copier le noeud et le traiter comme un objet DOM.
J'essais de filtrer le noeud avec le contenu d'un enfant. C'est là que je coince
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
<?php
$country = "portugal.xml";
$cat = "railway";
$filename= "SuperTest.xml";
 
         header("Pragma: public");
         header("Expires: 0");
         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
         header("Cache-Control: public");
         header("Content-Description: File Transfer");
         header("Content-Disposition: attachment; filename=$filename");
         header("Content-Type: application/force-download; charset=utf-8");
 
 
if(file_exists($country)) {
$xml = new XMLReader(); 
$xml->open($country); // input file as source
while($xml->read()){ 
   if($xml->nodeType == XMLReader::ELEMENT) { 
      if($xml->hasAttributes){ // vérifie que le noeud à des enfants
         if($xml->getattribute("k") == $cat) { // je compare les enfants pour coincidence avec ma variable $cat (railway)
 
         $node = $xml->expand();
         $dom = new DomDocument();
         $n = $dom->importNode($node,true);
         $dom->appendChild($n);
         $sxe = simplexml_import_dom($n);
         echo $sxe->asXML();
 
}
}
}
}
}
?>
J'obtiens ceci
Code xml :
1
2
3
4
5
 
    <?xml version="1.0"?>
    <tag k="railway" v="station"/>
    <?xml version="1.0"?>
    <tag k="railway" v="station"/>

Je souhaite retrouver les noeuds dans lesquel "station" se trouvent, complets parents et enfants:
Code xml :
1
2
3
4
5
6
7
8
9
10
11
12
 
<?xml version="1.0"?>
<osm>
  <node id="24984214" version="3" timestamp="2008-04-16T20:04:24Z" uid="8204" user="oha" changeset="162913" lat="38.6099096" lon="-9.1015325">
    <tag k="name" v="Fogueteiro"/>
    <tag k="railway" v="station"/>
  </node>
  <node id="25414227" version="4" timestamp="2009-02-28T21:08:53Z" uid="39787" user="jakomo" changeset="701481" lat="38.7457767" lon="-9.1354754">
    <tag k="name" v="Roma - Areeiro"/>
    <tag k="railway" v="station"/>
  </node>
</osm>

Si je supprime les deux conditions
Code :
1
2
3
 
         if($xml->hasAttributes){
         if($xml->getattribute("k") == $cat) {
la requête PHP me retourne bien un clone du premier xml (bien entendu sans conditions, donc complet).

Je ne sais pas si l'orientation que j'ai suivit me permettra d'aboutir à un résultat correct…
Merci de m'aiguiller, car là je sèche

Remiguel
Remiguel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2012, 14h05   #2
tsuji
Membre chevronné
 
Inscription : octobre 2011
Messages : 423
Détails du profil
Informations forums :
Inscription : octobre 2011
Messages : 423
Points : 698
Points : 698
Une façon de le faire est comme ça.
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
$dom = new DomDocument();
$root=$dom->createElement('osm');
$root=$dom->appendChild($root);
 
if(file_exists($country)) {
    $xml = new XMLReader(); 
    $xml->open($country); // input file as source
 
    $node=null;
    $kflag=false;
 
    while($xml->read()){ 
        if ($xml->nodeType==XMLReader::ELEMENT && $xml->name=='node') {
            $node=$xml->expand();
            $kflag=false;    //reset 
        }
 
        if ($kflag
            && $xml->nodeType==XMLReader::END_ELEMENT 
            && $xml->name=='node'
        ) {
            $root->appendChild($dom->importNode($node,true));
            $node=null;
            $kflag=false;
        }
 
        if (!$kflag
            && $xml->nodeType==XMLReader::ELEMENT 
            && $xml->name=='tag' 
            && $xml->getAttribute('k')
            && $xml->getAttribute('k')==$cat
        ) {
            $kflag=true;
        }
    }
}
 
$dom->formatOutput=true;
$dom->save($filename);
tsuji est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 24/09/2012, 20h28   #3
Remiguel
Invité de passage
 
Inscription : octobre 2003
Messages : 7
Détails du profil
Informations forums :
Inscription : octobre 2003
Messages : 7
Points : 1
Points : 1
Merci beaucoup tsuji

Je vais regarder ça et donnerais mes résultats des que possible.

Chapeau
Ton code en plus d'être parfait et opérationnel m'a permit d'apprendre à placer une balise vrai/faux propre et sauvegarder mon fichier sur le serveur.

Il ne me reste plus qu'à prendre garde à l'encodage du fichier output
Encore merci

Remiguel
Remiguel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 13h47   #4
jojona
Invité de passage
 
Inscription : juillet 2006
Messages : 4
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 4
Points : 3
Points : 3
Bonjour a tous,
Ca fait déjà quelques heures que je suis bloqué sur le problème de parsing d'un fichier xml.
Je ne suis pas un expert de l'utilisation de la classe XMLReader.
Ce que je voudrai faire c'est boucler à l'intérieur d'un noeud spécifique s'il le noeud langue est égal à fr, ensuite prendre les valeurs contenu dans la version correspondante
Code :
1
2
3
4
5
6
7
8
9
10
<film>
	<version>
		<langue>fr</langue>
		<titre>titre</titre>
	</version>
	<version>
		<langue>en</langue>
		<titre>titre</titre>
	</version>
</film>
Je vous remercie d'avance
jojona est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h37.


 
 
 
 
Partenaires

Hébergement Web