[DOM] Indentation XML

lux
Eléphant du PHP | 372 Messages

05 août 2007, 12:13

Bonjour tout le monde.
J'ai fait une petite recherche et pas trop trouvé ce que je voulais savoir. J'utilise DOM pour manipuler un fichier xml. Ça marche nickel, par contre j'ai une question par rapport à l'indentation.
$file = new DOMDocument("1.0");
$file->formatOutput = TRUE;
Quand je crée un document, et que j'ajoute les noeuds, les fils et le texte par la suite pas de problème, tout est bien indenté bien propre.

Par contre si par la suite j'ouvre le xml pour ajouter un fils :
$file = new DOMDocument();
$file->load("test.xml");
$file->formatOutput = TRUE;
Je peux mettre le formatOutput la ou je veux, il a joutera les élements à la que-leu-leu sans indentation.
Quelqu'un aurait une idée ? Merci d'avance 8-)

Petit nouveau ! | 3 Messages

07 août 2007, 15:38

Salut toi (tiens, c'est mon premier message ici, c'est dingue, salut tous le monde alors !) ;)

Qu'entend tu exactement par indentation ?

Je crains que tu ne fasse une petite confuse sur ce terme, l'indentation ce sont les tabulations que l'on place dans le code pour en assurer la lisibilité, dans ton cas, je présumes que tu voudrais juste passer à la ligne a chaque entrée.

Il va falloir regarder le code de l'objet que tu utilise pour voir comment il s'y prend, sinon, il faudra ajouter une méthode…

ViPHP
ViPHP | 928 Messages

07 août 2007, 15:48

Non je ne pense pas qu'il fasse de confusion, par indentation il entend une structure comme ceci :

Code : Tout sélectionner

<root> <child> <subchild>value</subchild> </child> </root>

Petit nouveau ! | 3 Messages

07 août 2007, 15:53

Le connaissant, il va se faire un plaisir de nous éclaircir tout ça ;)

lux
Eléphant du PHP | 372 Messages

09 août 2007, 10:41

Non je ne pense pas qu'il fasse de confusion, par indentation il entend une structure comme ceci :

Code : Tout sélectionner

<root> <child> <subchild>value</subchild> </child> </root>
Oui c'est exactement ça, comme je disais je peux atteindre ce résultat en faisant :
$file->formatOutput = TRUE;
Mais ça ne marche plus lors de l'ajout d'un fils. Ça ne marche que quand je crée le document.

T0T0
Invité n'ayant pas de compte PHPfrance

04 déc. 2007, 23:37

J'ai exactement le même problème que lux... et je n'ai pas encore trouvé de solution satisfaisante :(

Vous avez du nouveau à ce sujet ?

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

04 déc. 2007, 23:39

Je pense qu'il faut faire un coup de normalizeDocument() pour le remettre en forme, ce n'est pas automatique.

T0T0
Invité n'ayant pas de compte PHPfrance

05 déc. 2007, 00:24

Merci beaucoup Hubert Roksor pour cette réponse rapide :P

Cette nouvelle piste m'a redonné un peu d'espoir.
Malheureusement, je n'arrive toujours pas à obtenir le résultat escompté...
L'indentation ne marche que pour le premier enregistrement (comme l'a très bien expliqué lux).

Je continue de tester/chercher... :?

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 déc. 2007, 00:40

Je ne suis pas sûr de comprendre parce que chez moi ça marche, pourrais-tu stp poster un exemple minimal qui permet de reproduire ce problème ?

T0T0
Invité n'ayant pas de compte PHPfrance

05 déc. 2007, 10:21

Ok, voici mon test, en 2 étapes.

Etape 1 :
Lancer le fichier 'page1.php'

Code : Tout sélectionner

<?php //création d'un nouvel objet document $dom = new DOMDocument('1.0'); //création de l'élément racine 'contients' $continents = $dom->appendChild($dom->createElement('continents')); //ajout de l'élément 'Europe' comme enfant de 'continents' $Continent = $continents->appendChild($dom->createElement('Europe')); //ajout de pays européens comme enfants de 'Europe' $Pays = $Continent->appendChild($dom->createElement('pays', 'France')); $Pays = $Continent->appendChild($dom->createElement('pays', 'Espagne')); //on essaye de garder l'indentation $dom->formatOutput = true; $dom->normalizeDocument(); //on sauvegarde dans un fichier $dom->save('pays.xml'); ?>
Le fichier 'page1.php' génère un fichier 'pays.xml' dans lequel l'indentation fonctionne bien.


Etape 2 :
Lancer le fichier 'page2.php'

Code : Tout sélectionner

<?php //création d'un nouvel objet document $dom = new DOMDocument('1.0'); //ouverture du fichier précédemment créé $dom->load('pays.xml'); //ajout de l'élément 'Asie', comme enfant de 'continents' $continents = $dom->documentElement; $Continent = $continents->appendChild($dom->createElement('Asie')); //ajout de pays asiatiques comme enfants de 'Asie' $Pays = $Continent->appendChild($dom->createElement('pays', 'Japon')); $Pays = $Continent->appendChild($dom->createElement('pays', 'Chine')); //on essaye de garder l'indentation $dom->formatOutput = true; $dom->normalizeDocument(); //on sauvegarde dans un fichier $dom->save('pays.xml'); ?>
Le fichier 'page2.php' ajoute des éléments enfants dans l'arbre XML du fichier 'pays.xml'
Mais avec un code pourtant identique au précédent, l'indentation ne fonctionne plus : les derniers éléments ajoutés tiennent sur une seule ligne.


/!\ Si vous faites ce test, il ne faut pas ouvrir le fichier 'pays.xml' avec un navigateur internet, car ce dernier le met en forme automatiquement. Pour comprendre le problème d'indentation, il faut l'ouvrir avec Notepad++ par exemple.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 déc. 2007, 14:15

J'ai commencé à penser qu'il s'agissait d'un bug de PHP donc je suis allé voir sur leur bug tracker et la réponse se trouvait sur http://bugs.php.net/bug.php?id=27783

Avant ton $dom->load() il faut désactiver preserveWhiteSpace
//ouverture du fichier précédemment créé
$doc->preserveWhiteSpace = false;
$dom->load('pays.xml');

T0T0
Invité n'ayant pas de compte PHPfrance

05 déc. 2007, 16:40

Un énorme MERCI à toi Hubert, cette astuce fonctionne parfaitement !!! =D>

même si pour reprendre mon exemple, la variable s'appelle $dom (au lieu de $doc) :
$dom->preserveWhiteSpace = false;

Pour la peine, je vais m'enregistrer sur ce forum. C'est la moindre des choses ;)

lux
Eléphant du PHP | 372 Messages

05 déc. 2007, 22:37

Alors je vais mettre un résolu sur ce topic 8-)