Bonjour,
j'ai un menu qui vient d'un document xml :


<?xml version="1.0" encoding="iso-8859-1"?>
<categories>
  <category>
    <slug>Categorie A</slug>
    <name>Categorie A</name>
    <order>1</order>
    <catlevel1>
      <slug>Categorie A1</slug>
      <name>Categorie A1</name>
      <order>3</order>
      <catlevel2>
        <slug>Categorie A1 A</slug>
        <name>Categorie A1 A</name>
        <order>1</order>
      </catlevel2>
      <catlevel2>
        <slug>Categorie A1 B</slug>
        <name>Categorie A1 B</name>
        <order>2</order>
      </catlevel2>
    </catlevel1>
    <catlevel1>
      <slug>Categorie A2</slug>
      <name>Categorie A2</name>
      <order>5</order>
      <catlevel2>
        <slug>Categorie A2 A</slug>
        <name>Categorie A2 A</name>
        <order>1</order>
      </catlevel2>
    </catlevel1>
  <category>
    <slug>Categorie B</slug>
    <name>Categorie B</name>
    <order>2</order>
  </category>
  <category>
    <slug>Categorie C</slug>
    <name>Categorie C</name>
    <order>4</order>
    <catlevel1>
      <slug>Categorie C1</slug>
      <name>Categorie C1</name>
      <order>2</order>
    </catlevel1>
    <catlevel1>
      <slug>Categorie C2</slug>
      <name>Categorie C2</name>
      <order>1</order>
    </catlevel1>
  </category>
  <category>
    <slug>Categorie D</slug>
    <name>Categorie D</name>
    <order>5</order>
  </category>
  <category>
    <slug>Categorie E</slug>
    <name>Categorie E</name>
    <order>6</order>
  </category>
</categories>


que je retranscris en php en menu :


<?php
$menu .='<ul id="menu">';
$string=file_get_contents("myfile.xml");
$data = new SimpleXMLElement($string);
foreach ($data->category as $item){
	$menu .= '<li class="menuderoulant"><a href="index.php/component/virtuemart/'.$item->slug.'">'.$item->name;
	$menu .= '<ul class="menuderoulant2">';
   	foreach ($item->catlevel1 as $item2){
		$menu .= '<li><a href="index.php/component/virtuemart/'.$item->slug.'/'.$item2->slug.'">&nbsp;&nbsp;'.$item2->name.'</a>';
		$menu .= '<ul class="menuderoulant3">';
		foreach ($item2->catlevel2 as $item3){
			$menu .= '<li><a href="index.php/component/virtuemart/'.$item->slug.'/'.$item2->slug.'/'.$item3->slug.'">&nbsp;&nbsp;&nbsp;&nbsp;'.$item3->name.'</a></li>';
		}
	$menu .= '</ul></li>';
	}
	$menu .= '</ul></li>';
}

$menu .= '</ul>';
echo $menu;
?>



Seul soucis est que j'ai besoin de trier mes catégories / sous catégories et sous/sous catégories par order d'"order". J'ai beau faire le tour des fonction asort usort , etc. de php, je n'arrive pas à me trouver le bout de code pour retrier mes catégories simplement.
Existerait-il un moyen simple de trier directement par biais de la variable "order" de mes data->$items?
Sauf erreur de relacture de mon xml, mes balises <category> sont fermées, elles ont juste un certain nombre de nodes, entre autres <catlevel1> qui elles memes ont des nodes <catlevel2>.
+ mon xml s'affiche tout à fait correctement dans navigateur, qui ne serait pas le cas s'il y avait malformation au niveau du code xml.
enfin, je crois.
Le xml posté contient une erreur comme l'a précisé limipl, le nombre de category ouvrant ne correspond pas au nombre de category fermant. Cela se vérifie avec tout bon validateur (i.e http://www.w3schools.com/xml/xml_validator.asp), par ailleurs il suffisait juste de compter pour s'en assurer Smiley ohwell

Les navigateurs n'affichent pas toujours les erreurs ils sont assez laxistes et font tout pour afficher le contenu; sur ie par exemple, je vois bien le contenu sans erreur, sur chrome j'ai un message d'erreur que voici:

This page contains the following errors:

error on line 62 at column 21: Opening and ending tag mismatch: category line 0 and categories
Below is a rendering of the page up to the first error.

Modifié par floreo (30 Dec 2013 - 23:44)
bon, ok, mea culpa,
le xml est une copie de mon xml en ligne, j'avais par mégarde supprimer une balise en milieu de page.
Donc, le xml :


<?xml version="1.0" encoding="iso-8859-1"?>
<categories>
  <category>
    <slug>Categorie A</slug>
    <name>Categorie A</name>
    <order>1</order>
    <catlevel1>
      <slug>Categorie A1</slug>
      <name>Categorie A1</name>
      <order>3</order>
      <catlevel2>
        <slug>Categorie A1 A</slug>
        <name>Categorie A1 A</name>
        <order>1</order>
      </catlevel2>
      <catlevel2>
        <slug>Categorie A1 B</slug>
        <name>Categorie A1 B</name>
        <order>2</order>
      </catlevel2>
    </catlevel1>
    <catlevel1>
      <slug>Categorie A2</slug>
      <name>Categorie A2</name>
      <order>5</order>
      <catlevel2>
        <slug>Categorie A2 A</slug>
        <name>Categorie A2 A</name>
        <order>1</order>
      </catlevel2>
    </catlevel1>
  </category>
  <category>
    <slug>Categorie B</slug>
    <name>Categorie B</name>
    <order>2</order>
  </category>
  <category>
    <slug>Categorie C</slug>
    <name>Categorie C</name>
    <order>4</order>
    <catlevel1>
      <slug>Categorie C1</slug>
      <name>Categorie C1</name>
      <order>2</order>
    </catlevel1>
    <catlevel1>
      <slug>Categorie C2</slug>
      <name>Categorie C2</name>
      <order>1</order>
    </catlevel1>
  </category>
  <category>
    <slug>Categorie D</slug>
    <name>Categorie D</name>
    <order>5</order>
  </category>
  <category>
    <slug>Categorie E</slug>
    <name>Categorie E</name>
    <order>6</order>
  </category>
</categories>


excuses à limipl,
Donc, comment puis-je classer mes category / catlevel1 / catlevel2 par ordre order?
De tête je ne vois pas de solution simple et clefs en main, regarde du côté de xpath, il peut y avoir des trucs afin de simplifier. Pour moi tu dois faire une fonction récursive qui va parcourir chacune des catégories et ordonner comme il faut ses sous-catégories, voir sous-sous-catégories, et construire ton menu.
Oui, malheureusement, c'est un peu ce qui se passe, suis passé par un gros volume de boucles for(), cela fonctionne, reconstruit le menu tout à fait bien, mais c'est loin d'etre élégant. je cherche plutot une solution du genre asort ou usort mais ne parviens pas à l'encoder.
Merci.
Salut,
(bien après :s )
ça doit pouvoir se faire bien en xpath.
donc la fonction ça sera : $data->xpath("ici on mettra la requête qui va bien")

par contre, xpath ça remonte un peu ^^. Il y a sans doute des fonctions qui permettent de simplifier avec xpath2, mais je connais pas trop :s.

En solution pas efficace mais pas trop dur à écrire, on doit pouvoir faire des boucles imbriquer qui vont de order=1 jusqu'au order max.

Pour obtenir le order max des "category" :
$orderMaxCat=$data->xpath("/categories/category[not(/categories/category/order>order)]/order")
En gros on prend le order de la category tel que cette category a un order superieur aux orders des autres category.

Du coup ensuite on boucle de i=1 jusqu'a orderMaxCat
et on recommence pour chaque sous categorie :
$orderMaxLevel1=$data->xpath("/categories/category[order=".$i."]/catlevel1[not(/categories/category[order=".$i."]/catlevel1/order>order)]/order")

Et la pareil on boucle de j=1 jusqu'à $orderMaxLevel1
$orderMaxLevel2=$data->xpath("/categories/category[order=".$i."]/catlevel1[order=".$j."]/catlevel2[not(/categories/category[order=".$i."]/catlevel1[order=".$j."]/catlevel2/order>order)]/order")

Voila pour le principe Smiley biggrin (après je ne suis pas sur j'ai pas tester par contre Smiley lol )