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

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Avant:[regex]Supprimer ce qui ne correspond pas | Après:Supprimer des noeuds XML

par Arcanis » 14 oct. 2007, 18:19

Le bouton d'édition à disparu?!

Je pense avoir trouvé l'erreur: $case contient ceci, et donc $case{x'] et $case['y'] n'existent pas. Mais je ne sais pas comment atteindre x et y, j'ai essayé avec ça:
$case->@attributes['x']
$case->x
$case->['x']
$case['x']
$case['@attributes']['x']
Mais rien ne marche :?
SimpleXMLElement Object
(
[@attributes] => Array
(
[x] => 7
[y] => 9
)

[tile] => SimpleXMLElement Object
(
[@attributes] => Array
(
[niveau] => 1
[valeur] => 1,1,6
[deplacement] => 999
)

)

)

[edit1] Bouton retrouvé :mrgreen:
[edit2] Problème corrigé. Il fallait faire un foreach sur $xml->case au lieu de $xml

par Arcanis » 14 oct. 2007, 17:49

Yep, c'est fait avec le <?xsl-param> déclaré au début du fichier.
Je fait juste un
$xml = str_replace(array('[[:OFFSETX:]]','[[:OFFSETY:]]'),array($x,$y),$xml);
pour le personnaliser.

par Tracker » 14 oct. 2007, 17:46

Est-ce que tu as adapté les exemples donnés pour correspondre à la position actuelle du joueur ? J'imagine bien que la zone à conserver est dynamique, il te faut donc adapter les valeur ton XSL ou ton XPath vis-à-vis de la position du joueur.
+1
Ce qui revient à générer directement un xml personnalisé par user.

Tracker.

par Hubert Roksor » 14 oct. 2007, 17:44

Est-ce que tu as adapté les exemples donnés pour correspondre à la position actuelle du joueur ? J'imagine bien que la zone à conserver est dynamique, il te faut donc adapter les valeur ton XSL ou ton XPath vis-à-vis de la position du joueur.

par Arcanis » 14 oct. 2007, 17:38

Alors ça marche, mais en partie :/
En fait, certaines cases sont supprimées, mais ce ne sont pas les bonnes. Et certaines ne le sont pas, et ce sont celles à supprimer...

Je vais devoir utiliser un print_r colorié pour voir ce qui cloche :mrgreen:

par Hubert Roksor » 14 oct. 2007, 16:09

Est-ce que tu as essayé la solution de Tracker ? Il y a une petite erreur dans la condition du <xsl:if> mais sinon ça correspond à ce que tu cherches

Code : Tout sélectionner

<xsl:if test="@x >= -5 and @x <= 5 and @y >= -5 and @y <= 5">
Sinon, tu peux éventuellement le faire avec SimpleXML ou DOM, ou les deux. SimpleXML n'est pas fait pour supprimer des éléments, donc ce n'est pas particulièrement évident. Tu ne peux pas supprimer des éléments sur lesquels tu es en train d'itérer (en tout cas, pas à ma connaissance) donc tu dois les supprimer en deux temps : d'abord récupérer leurs positions dans la liste des éléments, puis ensuite supprimer effectivement les éléments. Avec comme piège le fait que chaque suppression fait remonter tous les éléments suivants d'un cran.

Pour référence, via SimpleXML (en imaginant que $cases représente le parent de tes éléments case)
$n = 0;
$del = array();

foreach ($cases as $case)
{
	if ($case['x'] > 5 || $case['x'] < -5 || $case['y'] > 5 || $case['y'] < -5)
	{
		$del[] = $n;
	}
	else
	{
		++$n;
	}
}

foreach ($del as $n)
{
	unset($cases->case[$n]);
}
Le même truc via SXE
$cases->deleteNodes('//case[@x < -5 or @x > 5 or @y < -5 or @y > 5]');
J'ai lu ça :
même en centièmes de secondes, c'est trop
...mais je pense que si tu en es à compter les centièmes tu as sûrement un problème ailleurs. Si le fichier existe apparement déjà, l'opération de suppression est le traitement principal de la page donc tu ne devrais pas te soucier de passer 0.01 ou 0.02 secondes... :-k

par Arcanis » 14 oct. 2007, 15:25

Non, il n'est pas généré pour lui.
En fait, j'ai codé un outil en Python qui code des cartes du monde sous forme de fichier xml (Kyria World Maker). La case en haut à gauche est la 1;1. Puis, dans ma base de données, j'ai les positions des joueurs (par exemple, 2;3 pour Babi, et 6;4 pour Babu). Tous les joueurs ont la même carte, mais des positions différentes.
Je positionne le joueur (et les cases) à l'aide des propriétées css "position", "top" et "left". Je met tout ceci dans une iframe, ce qui me permet de la recharger sans avoir à actualiser toute la page (c'est tjours ça de gagné ^^).
Donc je souhaiterais "élaguer" le fichier xml commun en fonction de la position des joueurs, pour que Babi n'ait accès qu'aux cases présentes entre -3 et 7 sur l'axe X, et -2 et 8 sur l'axe Y (je laisse une marge de 5 aux joueurs), et que Babu n'ait accès qu'aux cases présentes entre 1 et 11 sur l'axe X, et -1 et 9 sur l'axe Y.
Forcément, des cases seront vides (toutes celles inférieurs à 1), mais ça ce n'est pas grave.

par Tracker » 14 oct. 2007, 15:17

donc que tu as généré le contenu xml pour lui.
Donc pourquoi produire un contenu hors limites ?
Euh...comment ça? :o
Ton fichier, a priori contient des coordonnées de cases dont le centre est (0,0), pour un utilisateur tu filtres les cases en mettant comme contraintes (6<x<-6 et 6<y<-6), ce qui me fait dire que l'utilisateur est au centre et donc que le fichier xml lui est personnel (à été généré pour lui).

La remarque que j'apportais etait la suivant: si l'xml a été produit pour lui pourquoi avoir introduit des cases hors contraintes ?

Mais j'ai sans doute loupé une marche, alors ne tiens pas compte de ma remarque...

Tracker.

par Arcanis » 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

par Tracker » 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 ?

par Tracker » 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.

par Arcanis » 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).

par momox » 14 oct. 2007, 14:41

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

par Tracker » 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.

par Arcanis » 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.