Page 1 sur 1

Encore un Parser de fichier XML...

Posté : 30 déc. 2005, 03:20
par Ultiny
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.

Posté : 30 déc. 2005, 10:27
par nicolas
Si ton fichier est valide syntaxiquement, ne réinvente pas la roue et utilise simplexml ou domxml pour parser ton document.

Posté : 30 déc. 2005, 14:28
par Ultiny
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

Posté : 31 déc. 2005, 00:44
par Ultiny
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" }

Posté : 31 déc. 2005, 01:52
par Cyrano
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" }

Posté : 31 déc. 2005, 04:00
par Ultiny
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)

Posté : 31 déc. 2005, 11:13
par Cyrano
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]

Posté : 01 janv. 2006, 15:38
par Ultiny
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

Posté : 01 janv. 2006, 16:35
par Ultiny
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 );

Posté : 01 janv. 2006, 20:33
par Cyrano
remplace preg_match() par preg_match_all() peut-être ? ;)

Posté : 01 janv. 2006, 21:21
par Ultiny
:oops: Sans commentaires...

Merci

Posté : 06 févr. 2006, 13:14
par Ultiny
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.

Posté : 06 févr. 2006, 13:28
par Ultiny
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.

Posté : 06 févr. 2006, 13:38
par zeus
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 ;)