Aide pour recherche, traitement, remplacement de chaine XML

Eléphanteau du PHP | 34 Messages

20 août 2011, 14:28

Bonjour a tous !

C'est la première fois que je vient sur ce forum poster un message, car là, j'ai vraiment un gros problème, je n'arrive pas à trouver comment procéder. :D
Voilà le sujet:
Un utilisateur rentre dans un champ textarea un texte quelconque, et dans ce texte, il y aura des chaines de différents types:

Code : Tout sélectionner

posn="X.XXX Y.YYY Z.ZZZ" sizen="X.XXX Y.YYY" posn="X.X Y.Y Z.Z" sizen="X.X Y.Y" posn="X Y Z" sizen="X Y"
les valeurs X, Y et Z peuvent êtres de formats complètements différents, mais elles sont toujours présentes et sous forme de chiffre.


Ce que je voudrai faire, c'est récupérer tous les posn et sizen, récupérer leurs valeurs, X, Y et Z, les transformer, reconstituer le posn(ou sizen) et le remettre a ça place dans le champ texte (afficher le résultat n'est pas compliqué ensuite :mrgreen: )



Je n'ai pas beaucoup d'idées de la procédure, ayant cherché un peu partout, je patauge beaucoup sur ce projet. Merci d'avance pour votre aide. :priere:
Cordialement.

devlop78
Invité n'ayant pas de compte PHPfrance

20 août 2011, 15:38

Quel rapport avec XML ? Car si l'écriture respecte les mêmes règles que le XML (c-a-d pas d'échappement par \" mais par équivalent html), tu peux les concaténer et les inclure dans un environnement bien formaté pour ensuite les parser avec SimpleXML, par exemple. Mais sinon, une expression régulière ne suffit pas ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

20 août 2011, 15:42

salut,

les coordonnées sont toujours séparées par un espace ?

si oui
- récupérer ce qu'il y a entre les " (substr, preg_match comme tu veux ;) )
- explode sur les espaces, traiter le tableau résultat

ceci implique que les coordonnées soit toujours indiquer dans le sens x y z.

pour pouvoir traiter toutes les lignes un explode sur "\n" et un foreach sur le tableau résultat

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

20 août 2011, 15:44

Quel rapport avec XML ? Car si l'écriture respecte les mêmes règles que le XML (c-a-d pas d'échappement par \" mais par équivalent html), tu peux les concaténer et les inclure dans un environnement bien formaté pour ensuite les parser avec SimpleXML, par exemple. Mais sinon, une expression régulière ne suffit pas ?
He bien tout simplement que ces attributs sont inclus dans une balise XML, et je ne voit pas comment je peut récupérer les valeurs X Y et Z pour les modifier(avec SimpleXML, j'en suis sur, mais comment? :) )

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

20 août 2011, 18:24

au final ta question n'a rien a voir aevc ce que tu a mis ou mal posée ?

=> http://www.php.net/manual/fr/simplexmle ... ibutes.php ?

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

20 août 2011, 19:29

Désolé moogli, je n'avais pas vu ton premier post, je devais être en train d'écrire le mien.

Avec ce que tu m'a dit, j'y ai réfléchi, je vais tester quelque chose, mais a l'endroit où je vais uploader l'attribut, j'ai un doute, je verrai bien au moment du test ;)

Merci :D

Eléphanteau du PHP | 34 Messages

21 août 2011, 12:36

En fait, je vais vous donner un exemple pour que vous compreniez mieux mon problème, un utilisateur rentre ceci dans un champ html :
<quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/>
<label text="$i$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/>
Au final, il sortira comme cela :
<quad style="Bgs1InRace" substyle="BgList" posn="-153.750 -15.000 4.000" sizen="150.000 118.125" align="center" valign="center"/>
<label text="$i$fc0id : 496" posn="-5 38.4375 5" autonewline="1" scale="1" halign="right" valign="center"/>
Transformations effectuées :
Xfinal = Xdépart *320/128
Yfinal = Ydépart *180/96

et ce pour les attributs posn et sizen
Vous remarquerez que les valeurs peuvent être de différents formats.

Je doit donc récupérer les valeurs de posn et sizen pour chaque ligne, les transformer et les updater. Mais je ne sait pas trop comment faire cela avec SimpleXML, si vous pouviez m'éclairer SVP :D

Lorsque j'ai essayé d'utiliser SimpleXML, juste en récupérant le code XML, j'ai cette erreur :
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /homez.462/bossbrav/www/scripts/Maniaplanet/changement_taille_manialinks.php:47 Stack trace: #0 /changement_taille_manialinks.php(47): SimpleXMLElement->__construct('') #1 {main} thrown in /changement_taille_manialinks.php on line 47
Cordialement.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

21 août 2011, 15:06

hum au pif je dirais que c'est parce que c'est pas du xml complement valide ? (pas de début fin etc)

aller j'te mâche un peu le travail ;)
(c'est juste tiré de la doc que je t'ai déjà filé)
<?php
$string = <<<xml
<root>
    <item>
        <quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/>
        <label text="\$i\$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/>
    </item>
    <item>
        <quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/>
        <label text="\$i\$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/>
    </item>
</root>
xml;
/*
 * Xfinal = Xdépart *320/128
Yfinal = Ydépart *180/96
 */
$xml = simplexml_load_string($string);
echo '<pre>';
var_dump($xml);
echo '</pre>';
echo '<hr />';
foreach($xml->item as $it ) {
     $quadAtt = $it->quad->attributes();
     $l = explode(' ',$quadAtt->sizen);
     if (isset($l[0])) $l[0] = $l[0]*320/128;
     if (isset($l[1])) $l[1] = $l[1]*180/96;
     $quadAtt-> sizen = implode(' ',$l);
     $quadAtt = $it->quad->attributes();
     $l = explode(' ',$quadAtt->posn);
     if (isset($l[0])) $l[0] = $l[0]*320/128;
     if (isset($l[1])) $l[1] = $l[1]*180/96;
     $quadAtt-> posn = implode(' ',$l);
}
echo '<pre>';
var_dump($xml);
echo '</pre>';
?>
résultat :

Code : Tout sélectionner

object(SimpleXMLElement)#1 (1) { ["item"]=> array(2) { [0]=> object(SimpleXMLElement)#2 (2) { ["quad"]=> object(SimpleXMLElement)#4 (1) { ["@attributes"]=> array(6) { ["style"]=> string(10) "Bgs1InRace" ["substyle"]=> string(6) "BgList" ["posn"]=> string(20) "-61.500 -8.000 4.000" ["sizen"]=> string(13) "60.000 63.000" ["align"]=> string(6) "center" ["valign"]=> string(6) "center" } } ["label"]=> object(SimpleXMLElement)#5 (1) { ["@attributes"]=> array(6) { ["text"]=> string(14) "$i$fc0id : 496" ["posn"]=> string(9) "-2 20.5 5" ["autonewline"]=> string(1) "1" ["scale"]=> string(1) "1" ["halign"]=> string(5) "right" ["valign"]=> string(6) "center" } } } [1]=> object(SimpleXMLElement)#3 (2) { ["quad"]=> object(SimpleXMLElement)#5 (1) { ["@attributes"]=> array(6) { ["style"]=> string(10) "Bgs1InRace" ["substyle"]=> string(6) "BgList" ["posn"]=> string(20) "-61.500 -8.000 4.000" ["sizen"]=> string(13) "60.000 63.000" ["align"]=> string(6) "center" ["valign"]=> string(6) "center" } } ["label"]=> object(SimpleXMLElement)#4 (1) { ["@attributes"]=> array(6) { ["text"]=> string(14) "$i$fc0id : 496" ["posn"]=> string(9) "-2 20.5 5" ["autonewline"]=> string(1) "1" ["scale"]=> string(1) "1" ["halign"]=> string(5) "right" ["valign"]=> string(6) "center" } } } } } object(SimpleXMLElement)#1 (1) { ["item"]=> array(2) { [0]=> object(SimpleXMLElement)#2 (2) { ["quad"]=> object(SimpleXMLElement)#9 (1) { ["@attributes"]=> array(6) { ["style"]=> string(10) "Bgs1InRace" ["substyle"]=> string(6) "BgList" ["posn"]=> string(17) "-153.75 -15 4.000" ["sizen"]=> string(11) "150 118.125" ["align"]=> string(6) "center" ["valign"]=> string(6) "center" } } ["label"]=> object(SimpleXMLElement)#7 (1) { ["@attributes"]=> array(6) { ["text"]=> string(14) "$i$fc0id : 496" ["posn"]=> string(9) "-2 20.5 5" ["autonewline"]=> string(1) "1" ["scale"]=> string(1) "1" ["halign"]=> string(5) "right" ["valign"]=> string(6) "center" } } } [1]=> object(SimpleXMLElement)#3 (2) { ["quad"]=> object(SimpleXMLElement)#7 (1) { ["@attributes"]=> array(6) { ["style"]=> string(10) "Bgs1InRace" ["substyle"]=> string(6) "BgList" ["posn"]=> string(17) "-153.75 -15 4.000" ["sizen"]=> string(11) "150 118.125" ["align"]=> string(6) "center" ["valign"]=> string(6) "center" } } ["label"]=> object(SimpleXMLElement)#9 (1) { ["@attributes"]=> array(6) { ["text"]=> string(14) "$i$fc0id : 496" ["posn"]=> string(9) "-2 20.5 5" ["autonewline"]=> string(1) "1" ["scale"]=> string(1) "1" ["halign"]=> string(5) "right" ["valign"]=> string(6) "center" } } } } }
ce qu'il te reste a faire :
- factoriser la chose pour faire une belle fonction et pas avoir 4000 paquets dans le foreach :)
- faire ce que j'ai fait pour "quad" pour 'label'
- renvoyer l'objet sous forme de chaîne de caractère pour, et ben en faire ce que tu veux ;)
- si tu tiens au nb de zéro a près la virgule formater les nombres (number_format)


pourquoi <root></root> ? parce qu'il faut bien un début et une fin à ton arbre xml ;)
pourquoi <item></item> ? parce que ça permet d'en mettre plusieurs a la fois et de pas faire 44 fois une chose que tu peux faire qu'une ;)

évolution ? un beau formulaire qui mâche tout le boulot aux personnes qui rentre les chiffres (une case par attribut et tu génère le xml toi même, ça peux éviter toutes ces acrobaties ;) )

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

21 août 2011, 21:35

J'en demandai pas tant :mrgreen: mais merci bien, je vais tester cela demain matin ( ma connexion bug ce soir et ya des orages pas loin........)

il y a un truc qui est bizarre, pourquoi mettre deux fois :

Code : Tout sélectionner

<item> <quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/> <label text="\$i\$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/> </item>
tu voulais pas plutôt faire :

Code : Tout sélectionner

<item> <quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/> </item> <item> <label text="\$i\$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/> </item>

Sinon, l'erreur était bien parce que ce n'était pas du XML classique, entre autre, début et fin, oui....

Bref, je tient au courant :D

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

22 août 2011, 01:35

tu voulais pas plutôt faire :
Tout sélectionner
<item>
<quad style="Bgs1InRace" substyle="BgList" posn="-61.500 -8.000 4.000" sizen="60.000 63.000" align="center" valign="center"/>
</item>
<item>
<label text="\$i\$fc0id : 496" posn="-2 20.5 5" autonewline="1" scale="1" halign="right" valign="center"/>
</item>
Nan je pensais simplement que quad et label était deux chose nécéssaire pour ton fonctionnement ^^

après c'est un exemple tu fait ce que tu veux ^^

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

22 août 2011, 09:27

Voilà, c'est adapté, reste plus qu'a transformer ça :
SimpleXMLElement::__set_state(array(
'item' =>
SimpleXMLElement::__set_state(array(
'quad' =>
SimpleXMLElement::__set_state(array(
'@attributes' =>
array (
'style' => 'Bgs1InRace',
'substyle' => 'BgList',
'posn' => '-153.75 -15 4.000',
'sizen' => '150 118.125',
'align' => 'center',
'valign' => 'center',
),
)),
'label' =>
SimpleXMLElement::__set_state(array(
'@attributes' =>
array (
'text' => '$i$fc0id : 496',
'posn' => '-5 38.4375 5',
'autonewline' => '1',
'scale' => '1',
'halign' => 'right',
'valign' => 'center',
),
)),
)),
))

en ça :
<quad style="Bgs1InRace" substyle="BgList" posn="-153.750 -15.000 4.000" sizen="150.000 118.125" align="center" valign="center"/>
<label text="$i$fc0id : 496" posn="-5 38.4375 5" autonewline="1" scale="1" halign="right" valign="center"/>
Bon, ben, c'est parti.........

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

22 août 2011, 09:58

ton bonheur http://www.php.net/manual/fr/simplexmlelement.asxml.php ^^

sérieux regarde un peu la liste des méthodes de la classe y a tout dedans :)

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

22 août 2011, 10:08

J'étais parti avec AsXML, oui, merci quand même :D

Mais moi il ne m'affiche rien, ce doit être parce que le format d'entrée de $xml n'est pas adapté non ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

22 août 2011, 10:24

sa affiche pas sa retourne une chaine donc un faut echo en plus.

fait voir ton code ça sera plus simple ^^
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 34 Messages

22 août 2011, 10:36

Oui, j'ai bien mis l'echo devant......

La fin de mon code :

Code : Tout sélectionner

echo '<pre>'; var_dump($xml); echo '</pre>'; echo $xml->asXML();

EDIT : Je n'ai rien dit, ça fonctionne, comme je ne voulais pas d'echo, j'ai fait :

Code : Tout sélectionner

$_SESSION['code_final'] = $xml->asXML();
Puis un echo de cette session, et mon code est affiché correctement.
Il me reste 2-3 bidouilles a effectuer pour alléger le code et puis ça va être fini :D