Avant:[regex]Supprimer ce qui ne correspond pas | Après:Supprimer des noeuds XML

Eléphant du PHP | 99 Messages

14 oct. 2007, 13:13

Salut!
J'ai un texte de ce type:

Code : Tout sélectionner

<case x='2' y='3'>[...]</case>
mis sur deux bonnes centaines de lignes, et je souhaiterais supprimer toutes les balises dans lequelles les attributs X et Y ne sont pas entre un interval de nombre. J'ai essayé [^-6-6] mais, ôh surprise, ça n'a pas marché. Etrange...
J'ai ensuite essayé les assertions négatives, mais faut croire que j'ai quelques problèmes à les comprendre, parce que le résultat n'est pas vraiment celui que j'attends. En fait, rien n'est remplacé...

Ma regexp actuelle:

Code : Tout sélectionner

#<case x='(?!(-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6))[0-9]+' y='(?!(-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6))[0-9]+'>.*<\/case>#Us
et j'ai aussi essayé l'assertion arrière, vu que je ne réussis pas à me souvenir les différences entre les deux

Code : Tout sélectionner

#<case x='(?<!(-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6))[0-9]+' y='(?<!(-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6))[0-9]+'>.*<\/case>#Us
Si vous savez comment faire, je suis preneur :D
Le but est d'arriver à:
<?php $result = preg_replace($regex,'',$texte); ?>
Pour supprimer tout.

Merci d'avance!
Modifié en dernier par Arcanis le 14 oct. 2007, 18:25, modifié 1 fois.

Eléphant du PHP | 443 Messages

14 oct. 2007, 13:22

Salut,

Tu veux dire quoi par:
je souhaiterais supprimer toutes les balises dans lequelles les attributs X et Y ne sont pas entre un interval de nombre

Tu peux donner un exemple ?

Tracker.

Eléphant du PHP | 99 Messages

14 oct. 2007, 13:32

Code d'entrée:

Code : Tout sélectionner

<case x='7' y='7'> <tile niveau='1' valeur='1,1,6' deplacement='999' /> <tile niveau='2' valeur='2,0,4' deplacement='0' /> </case> <case x='5' y='8'> <tile niveau='1' valeur='1,1,6' deplacement='999' /> <tile niveau='2' valeur='2,2,4' deplacement='0' /> </case> <case x='5' y='9'> <tile niveau='1' valeur='1,1,6' deplacement='999' /> </case> <case x='3' y='8'> <tile niveau='1' valeur='1,1,6' deplacement='999' /> <tile niveau='2' valeur='2,1,4' deplacement='0' /> </case> <case x='3' y='9'> <tile niveau='1' valeur='1,1,6' deplacement='999' /> </case> <case x='5' y='2'> <tile niveau='1' valeur='1,0,0' deplacement='1' /> <tile niveau='2' valeur='2,1,18' deplacement='1' /> <tile niveau='3' valeur='3,0,6' deplacement='0' /> </case>
Code censé sortir:

Code : Tout sélectionner

<case x='5' y='2'> <tile niveau='1' valeur='1,0,0' deplacement='1' /> <tile niveau='2' valeur='2,1,18' deplacement='1' /> <tile niveau='3' valeur='3,0,6' deplacement='0' /> </case>
Car tout les autres comportent soit un attribut 6<X ou X<-6, soit un attribut 6<Y ou Y<-6.

Eléphant du PHP | 443 Messages

14 oct. 2007, 13:46

Je pense que tu aurais meilleurs compte de faire ton traitement en xsl.
Je regarde, si j'ai une solution, je te la colle.

Tracker.

Mammouth du PHP | 1511 Messages

14 oct. 2007, 13:46

Tu peux parcourir tes nodes avec simplexml, ca sera plus simple qu'une regex ;)
En ajoutant en plus l'extension de la classe par hubert roksor(cf http://www.phpfrance.com/forums/voir_sujet-32317.php) tu peux faire quelque chose d'assez bien ;)

Eléphant du PHP | 99 Messages

14 oct. 2007, 13:50

En fait, je code un jeu en ligne avec une carte du monde au format XML+XSL. Comme un jeu de ce type possède un grand nombre de rafraichissement de la page, je préfère économiser au maximum les temps de traitements, en utilisant de préférence l'analyseur intégré du navigateur. Et le seul truc que j'aurais à faire, dans ce cas, serait supprimer du fichier xml les cases à ne pas afficher.

ViPHP
ViPHP | 4039 Messages

14 oct. 2007, 14:02

alors pourquoi du php ? si c'est pour soulager le serveur, j'opterais pour du javascript pour afficher le terrain..
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

14 oct. 2007, 14:10

Je pense qu'il faudrait que tu expliques de manière concise ce que tu veux vraiment faire, parce que d'après ce que je lis, si tu traites le XML par XSLT du côté du client alors tu n'as même pas besoin d'éliminer les éléments indésirables, tu n'as qu'à ne pas les traiter. (ajouter une clause à ton XSLT pour les ignorer)

Eléphant du PHP | 99 Messages

14 oct. 2007, 14:18

Pour éviter la triche.
Certains qui s'y connaitraient un peu en html/javascript pourraient penser à récupérer la carte entière, à empêcher la suppression des cases innaccessibles, et donc obtenir le terrain entier. Le fait de le faire coté serveur empêche ça.

Eléphant du PHP | 443 Messages

14 oct. 2007, 14:37

Je sais pas si ça peut t'aider, regarde le code suivant:
<?php
$strXML = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <case x='7' y='7'>
       <tile niveau='1' valeur='1,1,6' deplacement='999' />
       <tile niveau='2' valeur='2,0,4' deplacement='0' />
   </case>
   <case x='5' y='8'>
       <tile niveau='1' valeur='1,1,6' deplacement='999' />
       <tile niveau='2' valeur='2,2,4' deplacement='0' />
   </case>
   <case x='5' y='9'>
       <tile niveau='1' valeur='1,1,6' deplacement='999' />
   </case>
   <case x='3' y='8'>
       <tile niveau='1' valeur='1,1,6' deplacement='999' />
       <tile niveau='2' valeur='2,1,4' deplacement='0' />
   </case>
   <case x='3' y='9'>
       <tile niveau='1' valeur='1,1,6' deplacement='999' />
   </case>
   <case x='5' y='2'>
       <tile niveau='1' valeur='1,0,0' deplacement='1' />
       <tile niveau='2' valeur='2,1,18' deplacement='1' />
       <tile niveau='3' valeur='3,0,6' deplacement='0' />
   </case>
</root>
XML;

$strXSL = <<<XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<root>
			<xsl:for-each select="//case">
				<xsl:if test="@x < 6 and @x > -6 and @y < 6 and @y > -6">
					<xsl:copy-of select="." />
				</xsl:if>
			</xsl:for-each>
		</root>
	</xsl:template>
</xsl:stylesheet>
XSL;

// xml
$dom_object = new DomDocument();
$dom_object->loadXML($strXML);

// xsl
$xsl_obj = new DomDocument();
$xsl_obj->loadXML($strXSL);

$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl_obj);
$result = $proc->transformToXML($dom_object);

header('content-type: text/plain');
var_dump($result); 
?>
Tracker.

Mammouth du PHP | 1511 Messages

14 oct. 2007, 14:41

Attention a corriger la condition xslt, les < et > on été transformés en entités html ;)

Eléphant du PHP | 99 Messages

14 oct. 2007, 14:45

Oui, j'avais utilisé un code de ce genre avant. Mais j'aimerais utilser le minimum de ressources possible avec le script. Or utiliser un traitement php sur le serveur prends toujours un certains temps (même en centièmes de secondes, c'est trop).

Eléphant du PHP | 443 Messages

14 oct. 2007, 14:46

Attention a corriger la condition xslt, les < et > on été transformés en entités html ;)
Non, c'est fait pour, les comparateurs en xsl s'écrivent < ou >

Tracker.

Eléphant du PHP | 443 Messages

14 oct. 2007, 14:51

Oui, j'avais utilisé un code de ce genre avant. Mais j'aimerais utilser le minimum de ressources possible avec le script. Or utiliser un traitement php sur le serveur prends toujours un certains temps (même en centièmes de secondes, c'est trop).
Si tu mets des bornes -6 > x/y > 6, ça veut dire que l'utilisateur est au centre de la carte, donc que tu as généré le contenu xml pour lui.
Donc pourquoi produire un contenu hors limites ?

Eléphant du PHP | 99 Messages

14 oct. 2007, 15:07

donc que tu as généré le contenu xml pour lui.
Donc pourquoi produire un contenu hors limites ?
Euh...comment ça? :o