Encore un Parser de fichier XML...

ViPHP
ViPHP | 656 Messages

30 déc. 2005, 03:20

Bonsoir,

J'aimerais créer une petite fonction pour parser un fichier XML simple.
La structure de mon fichier est de type XML mais n'est en rien dans un standard valide, j'utilise mes balises personnelles.

Voici à quoi ressemblera chaque fichier:

<nomBalise name="unNomUnique" type="String/Bool/Int">
Un texte, un nombre ou une valeur boolean
</nomBalise>

Je souhaiterais donc récuperer le tout dans soit:

$unNomUnique["value"] (de préfèrence cette methode)
$unNomUnique["type"]

soit:

$answer["name"]["value"]
$answer["name"]["type"]

Mais le sous tableau est moins pratique.

Merci de votre aide.

Eléphant du PHP | 353 Messages

30 déc. 2005, 10:27

Si ton fichier est valide syntaxiquement, ne réinvente pas la roue et utilise simplexml ou domxml pour parser ton document.

ViPHP
ViPHP | 656 Messages

30 déc. 2005, 14:28

C'est vrai que simpleXML est pas mal mais malheureusement pour moi j'ai l'intention de mettre du code HTML entres mes balises customs.

Je voudrais faire des feuilles de templates pour un site avec.

Quelqu'un connait il une méthode? ou un parser maison ou on spécifit les balises?

Merci

ViPHP
ViPHP | 656 Messages

31 déc. 2005, 00:44

Voilà j'ai opté pour eregi qui me permet de récuperer dans un tableau toutes les variables necessaires.
J'ai toute fois un petit soucis avec l'histoire des " c'est a dire que l'orsque je delimite la chaine à récuperer entre " et " et qu'il y à un autre " plus loin dans la chaine à traiter, il prendra le dernier comme la fin de delimitation alors que je voudrais qu'il prenne le premier.

Voici mon moceau de code:
<?php

$texte="<balise name=\"header\" type=\"integer\">Utiliser des regexp via PHP</balise>";

eregi("<balise(.*)name=(\"|')(.*)(\"|')(.*)>(.*)</balise>", $texte, $regs); 

var_dump($regs);

?>
Voici le resultat de ce script:

Code : Tout sélectionner

array(7) { [0]=> string(58) "<balise name="header" type="integer">Utiliser des regexp via PHP</balise>" [1]=> string(1) " " [2]=> string(1) """ [3]=> string(21) "header" type="integer" [4]=> string(1) """ [5]=> bool(false) [6]=> string(27) "Utiliser des regexp via PHP" }
Et celui attendu:

Code : Tout sélectionner

array(7) { [0]=> string(73) "<balise name="header" type="integer">Utiliser des regexp via PHP</balise>" [1]=> string(1) " " [2]=> string(1) """ [3]=> string(6) "header" [4]=> string(1) """ [5]=> string(15) " type="integer"" [6]=> string(27) "Utiliser des regexp via PHP" }

Mammouth du PHP | 19672 Messages

31 déc. 2005, 01:52

Proposition avec preg_match :
<?php

$texte = "<balise name=\"header\" type=\"integer\">Utiliser des regexp via PHP</balise>";

$masque = "#<balise(.*)name=(\"|')(\w*)(\"|')(\s?.*)>(.*)</balise>#i";

preg_match($masque, $texte, $regs);
?>
<pre>
<?php
var_dump($regs);
?>
</pre>
Le résultat :

Code : Tout sélectionner

array(7) { [0]=> string(73) "<balise name="header" type="integer">Utiliser des regexp via PHP</balise>" [1]=> string(1) " " [2]=> string(1) """ [3]=> string(6) "header" [4]=> string(1) """ [5]=> string(15) " type="integer"" [6]=> string(27) "Utiliser des regexp via PHP" }
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
ViPHP | 656 Messages

31 déc. 2005, 04:00

Ohhhh :o

Je ne savais même pas que preg_match savait faire ça, je le croyais limité à la recherche d'une chaine.

Encors une fois merci pour ce débloquage. (car j'étais bloquer)

Mammouth du PHP | 19672 Messages

31 déc. 2005, 11:13

La différence entre eregi et preg_match, c'est que le premier utilise des expressions POSIX, la seconde des expressions PCRE. En outre, l'utilisation des PCRE est plus rapide à l'exécution. Ceci dit, beaucoup d'expressions POSIX sont quasiment directement utilisables en lieu et place d'expressions PCRE pour peu qu'on y ajoute des délémiteurs et éventuellement des options .

Tu as sur le site un tuto sur l'utilisation des PCRE qui t'apportera peut-être quelques lumières supplémentaires :)

N'oublie pas le [Résolu]
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
ViPHP | 656 Messages

01 janv. 2006, 15:38

Cyrano on sent tout de suite le professionel !

Ta même placé (\w*) pour le nom que sera mon id de tableau afin qu'il soit valide. Je t'en remercie.

Et de plus merci pour le tuto car je ne l'avais jamais vu et je cherchais à me faire un petit tableau avec tous les "(.*?), (.*),..." avec leur signification.

Problème résolu

ViPHP
ViPHP | 656 Messages

01 janv. 2006, 16:35

Ah finalement maintenant j'ai un autre problème.

Il me mets bien le resultat en array mais il le fait qu'une seule fois, hors moi on va rencontrer plusieurs fois les balises qui contiendrons un texte et des propriétées différentes.

Voici en faite ce que je souhaiterais rentrer par exemple dans la fonction (il n'y aura pas que ces 2 balises, mais sans doute encors beaucoup d'élements du site) :

Code : Tout sélectionner

<balise name="header">Utilisez PHP</balise><balise name="footer">Utilisez MySQL</balise>
Voici ce que j'aimerais qu'il en sorte:

Code : Tout sélectionner

array(2) { [0]=> array(6) { [0]=> string(43) "<balise name="header">Utilisez PHP</balise>" [1]=> string(1) " " [2]=> string(1) """ [3]=> string(6) "header" [4]=> string(1) """ [5]=> string(12) "Utilisez PHP" } [1]=> array(6) { [0]=> string(45) "<balise name="footer">Utilisez MySQL</balise>" [1]=> string(1) " " [2]=> string(1) """ [3]=> string(6) "footer" [4]=> string(1) """ [5]=> string(14) "Utilisez MySQL" } }
Merci pour votre aide.

Edit:

J'ajoute ceci (simulation de la fonction) pour aider ceux qui veulent m'aider :)
$this->tempOne = array( "<balise name=\"header\">Utilisez PHP</balise>", " ", "\"", "header", "\"", "Utilisez PHP" );
		$this->tempTwo = array( "<balise name=\"footer\">Utilisez MySQL</balise>", " ", "\"", "footer", "\"", "Utilisez MySQL" );
		$this->parsed = array( $this->tempOne, $this->tempTwo );

Mammouth du PHP | 19672 Messages

01 janv. 2006, 20:33

remplace preg_match() par preg_match_all() peut-être ? ;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
ViPHP | 656 Messages

01 janv. 2006, 21:21

:oops: Sans commentaires...

Merci

ViPHP
ViPHP | 656 Messages

06 févr. 2006, 13:14

Ba finalement je retire la mention "Résolu" car j'ai un problème.

Ma class ne fonctionne pas comme voulu, elle ne lit que la dernière portion de HTML :
	private function parse( $themesFolder, $themesFile )
	{
		$this->themesFolder = $themesFolder;
		$this->themesFile = $themesFile;
		$this->contents = $this->getFile( $this->themesFolder, $this->themesFile );

		if ( ! preg_match_all( "#<template(.*)name=(\"|')(\w*)(\"|')>(.*)</template>#is", $this->contents, $this->parsed, PREG_SET_ORDER ) )
		{
			$this->functionsClass->errorReport( 3, __FILE__, __LINE__ - 2, "main.xml' or '".$this->themesFile.".xml' in '".$this->themesFolder );
		}

		return $this->parsed;
	}
La fonction getFile() retourne le contenu du fichier XML.

Merci pour votre aide.

ViPHP
ViPHP | 656 Messages

06 févr. 2006, 13:28

Ah je crois avoir trouvé.

J'ai rajouté l'option U pour rendre les quantificateurs non gourmands et ça marche visiblement.

Je laisse ouvert ce topic car j'aurais sans doute d'autres problèmes à ce sujet.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

06 févr. 2006, 13:38

Non, je le met en RESOLU car tu as résolu 2 de tes problèmes.

Si tu as un nouveau problème sur ce sujet, je t'encourage à ouvrir un nouveau topic en faisant un lien sur celui là

Comme ca, on évite de mélanger les sujets et tu ne décourage pas ceux qui veulent t'aider mais qui ne veulent pas tout lire ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer