Bonjour
je voudrais faire une transformation XSL vers html "à plat et alphabétiquement" côté client d'un fichier xml représentant un menu vertical hiérarchique (c-à-d avec dossier et sous-dossier dont le niveau d'imbrication peut être multiple et n'est pas connu à priori)
Smiley rolleyes La difficulté pour moi est de tester l'imbrication des dossiers sachant que chaque élément du fichier xml, chaque item du menu, possède juste 4 informations: son nom, son type (menu, dossier ou contenu) l'identifiant unique de son dossier parent (1=master étant le premier niveau) et un identifiant unique donc.
ex xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="menu.xsl" type="text/xsl"?>
<plist>
  <item>
    <nom>master</nom>
    <type>menu</type>
    <parent></parent>
    <idunique>1</idunique>
  </item>
  <item>
    <nom>Dossier2</nom>
    <type>dossier</type>
    <parent>1</parent>
    <idunique>2</idunique>
  </item>
  <item>
    <nom>Dossier1</nom>
    <type>dossier</type>
    <parent>1</parent>
    <idunique>3</idunique>
  </item>
  <item>
    <nom>DossierX</nom>
    <type>dossier</type>
    <parent>5</parent>
    <idunique>4</idunique>
  </item>
  <item>
    <nom>Dossier</nom>
    <type>dossier</type>
    <parent>2</parent>
    <idunique>5</idunique>
  </item>
  <item>
    <nom>DossierY</nom>
    <type>dossier</type>
    <parent>5</parent>
    <idunique>6</idunique>
  </item>
  <item>
    <nom>Element</nom>
    <type>contenu</type>
    <parent>3</parent>
    <idunique>7</idunique>
  </item>
  <item>
    <nom>ElementA</nom>
    <type>contenu</type>
    <parent>4</parent>
    <idunique>8</idunique>
  </item>
  <item>
    <nom>ElementB</nom>
    <type>contenu</type>
    <parent>4</parent>
    <idunique>9</idunique>
  </item>
  <item>
    <nom>Element1</nom>
    <type>contenu</type>
    <parent>6</parent>
    <idunique>10</idunique>
  </item>
  <item>
    <nom>Element1</nom>
    <type>contenu</type>
    <parent>1</parent>
    <idunique>11</idunique>
  </item>
  <item>
    <nom>Element3</nom>
    <type>contenu</type>
    <parent>1</parent>
    <idunique>12</idunique>
  </item>
  <item>
    <nom>Element2</nom>
    <type>contenu</type>
    <parent>1</parent>
    <idunique>13</idunique>
  </item>
  <item>
    <nom>Element2</nom>
    <type>contenu</type>
    <parent>6</parent>
    <idunique>14</idunique>
  </item>
  <item>
    <nom>Element</nom>
    <type>contenu</type>
    <parent>2</parent>
    <idunique>15</idunique>
  </item>
</plist>


je voudrais obtenir (pour le moment) ce genre de résultat simple "à plat":

Master.
-Dossier1.
--Element.
-Dossier2.
--Dossier.
---DossierX.
----ElementA.
----ElementB.
---DossierY.
----Element1.
----Element2.
--Element.
-Element1.
-Element2.
-Element3.

J'aimerais que quelqu'un me mette sur la voie, m'indiquant un lien ou un nom de méthode.
Ce doit être un cas classique qui doit s'appliquer à des menus déroulants verticaux comme à des sommaires.

Note: j'ai crée un AppleScript qui génère ce type de fichier xml à partir du menu playlist d'iTunes pour ceux que ça intéresse et pour vous donner une idée de ce que j'essaie de reproduire.

J'espère que cela vous intéressera
Merci.
Smiley smile
Modifié par dj DMSR (27 Sep 2007 - 14:03)
Après avoir un peu potassé j'ai quelques questions:

1/ un template peut-il s'appeler lui-même?
si dans le template il y a un test conditionnel qui si il est vérifié implique un re-appel de lui-même et une ré-assignation de la variable de test peut-on passer cette variable sachant qu'on changera de noeud (va-t-elle persister)?

2/quel est l'intérêt d'utiliser des attributs plutôt que des balises?
outre le fait qu'on diminue un peu le poids du document (pour un usage web) quelle-est l'incidence sur le temps de traitement?

3/indidence de la balise <?xml-stylesheet... dans le cas d'une utilisation dans un autre document xml via document():
Dans ce cas faut-il la supprimer du fichier qui sera inclus?
Y a-t-il risque de conflit ou la feuille de style ainsi déclarée sera ignorée?

Merci
Premier essai

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:variable name="IDcurrentFolder">1</xsl:variable>
<xsl:template match="/">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css" media="all">
li {
	list-style:none
}
</style>
<title>Menu</title>
</head>

<body>
<xsl:call-template name="master" />
</body>
</html>

</xsl:template>
  <xsl:template name="master">
    <ul><xsl:call-template name="dossier" /></ul>
    <ul><xsl:call-template name="contenu" /></ul>
  </xsl:template>

  <xsl:template name="dossier">
    <xsl:for-each select="plist/item">
     <xsl:sort select="." order="ascending" />
        <xsl:if test="type = 'dossier' and parent = $IDcurrentFolder">
              <xsl:element name="li">
                <xsl:value-of select='nom' />
              </xsl:element>
              
              <-- Traitement récursif des sous-dossiers -->
              <xsl:variable name="IDcurrentFolder" select='idunique' />
              <xsl:call-template name="master" />

        </xsl:if>
    </xsl:for-each> 
  </xsl:template>

  <xsl:template name="contenu">
    <xsl:for-each select="plist/item">
     <xsl:sort select="." order="ascending" />
      <xsl:if test="type = 'contenu' and parent = $IDcurrentFolder">
          <xsl:element name="li">
      		<xsl:value-of select='nom' />
          </xsl:element>
      </xsl:if>
    </xsl:for-each> 
  </xsl:template>

</xsl:stylesheet>


J'obtiens les élements du premier niveau mais le traitement récursif des dossiers imbriqués ne se fait pas... ?
Modifié par dj DMSR (21 Sep 2007 - 16:39)
essai avec param plutôt que variable:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:output method="html" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:param name="IDcurrentFolder" select="1" />
<xsl:template match="/">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css" media="all">
li {
	list-style:none
}
</style>
<title>Menu</title>
</head>
 
<body>
<xsl:call-template name="dossier" />
</body>
</html>
 
</xsl:template>
 
  <xsl:template name="dossier">
    <xsl:for-each select="plist/item">
     <xsl:sort select="." order="ascending" />
        <xsl:if test="type = 'dossier' and parent = $IDcurrentFolder">
          <xsl:element name="li">
            <xsl:value-of select='nom' />
          </xsl:element>
          <xsl:call-template name="dossier"><xsl:with-param name="IDcurrentFolder" select="idunique" /></xsl:call-template>
        </xsl:if>
    </xsl:for-each>
    <xsl:call-template name="contenu"><xsl:with-param name="IDcurrentFolder" select="$IDcurrentFolder" /></xsl:call-template>
  </xsl:template> 
  
  <xsl:template name="contenu">
    <xsl:for-each select="plist/item">
     <xsl:sort select="." order="ascending" />
      <xsl:if test="type = 'contenu' and parent = $IDcurrentFolder">
          <xsl:element name="li">
            <xsl:value-of select='nom' />
          </xsl:element>
      </xsl:if>
    </xsl:for-each> 
  </xsl:template>
 
</xsl:stylesheet>


Il n'y a plus de template master, juste dossier et contenu.
J'ai également changé le "Traitement récursif des sous-dossiers"
par un "call template with param" mais ...
ça ne marche toujours pas
pas de plantage, ça n'affiche que le premier niveau (item(s) avec id=1 pour parent):

Dossier1
Dossier2
Element1
Element2
Element3
Modifié par dj DMSR (22 Sep 2007 - 18:40)
Il fallait utiliser un xsl:key plutôt qu'une variable ou un param


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:key name="cle" match="item" use="parent"/>
<xsl:template match="/">
		<xsl:apply-templates select="plist/item[not(parent)]" />
</xsl:template>

<xsl:template match="item">
    <xsl:value-of select="nom"/><br />
    <xsl:apply-templates select="key('cle',idunique)">
    <xsl:sort select="nom" order="ascending" />           
    </xsl:apply-templates>
</xsl:template>
 
</xsl:stylesheet>


On obtient:

master
Dossier1
Element
Dossier2
Dossier
DossierX
ElementA
ElementB
DossierY
Element1
Element2
Element
Element1
Element2
Element3

Merci à Erwy du forum des développeurs.

Reste à décaler (de la marge gauche) le contenu d'un dossier par rapport à son dossier conteneur en utilisant pour cela un "-" à chaque décalage.
Je veux toujours:

Master.
-Dossier1.
--Element.
-Dossier2.
--Dossier.
---DossierX.
----ElementA.
----ElementB.
---DossierY.
----Element1.
----Element2.
--Element.
-Element1.
-Element2.
-Element3.
Modifié par dj DMSR (27 Sep 2007 - 13:58)
Voici la solution:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"
 encoding="UTF-8"
 doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
 doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:key name="cle" match="item" use="parent"/>
<xsl:template match="/">
		<xsl:apply-templates select="plist/item[not(parent)]">
        <xsl:with-param name="tiret" select="''"/>
			<xsl:sort select="nom" order="ascending"/>
        </xsl:apply-templates>
</xsl:template>

<xsl:template match="item">
		<xsl:param name="tiret"/>
		<xsl:value-of select="concat($tiret,'',nom)"/>
		<br/>
		<xsl:apply-templates select="key('cle',idunique)">
			<xsl:with-param name="tiret" select="concat($tiret,'-')"/>
			<xsl:sort select="nom" order="ascending"/>
		</xsl:apply-templates>
	</xsl:template>
</xsl:stylesheet>


On obtient bien:
master
-Dossier1
--Element
-Dossier2
--Dossier
---DossierX
----ElementA
----ElementB
---DossierY
----Element1
----Element2
--Element
-Element1
-Element2
-Element3
Smiley langue

Un Grand merci à Erwy du Forum des développeurs
bonjour,

je voudrais crée une partie de mon site avec du xml (sommaire et tableau).

En regardant votre code (qui me conviendrais bien) j'arrive pas a le visualisée sur IE7...

j'ai bien collé votre code (dans un fichier : menu.xml) ainsi que le xsl (voici la solution), et en ouvrant le xml rien naparet sur mon ecran (jutilise windows Xp avec EI7)...

J'ai volu tester ausi les xsl du 27 Sep 2007 - 01:12:33, et la meme probleme..

par contre les deux autre premier s'affiche bien...

En gros je bloque tjrs sur le sommaire avec hyrarchie pour passer a latape suivante, generer les tableaux suvant le sommaire (la forme du tableau et deja effectuer).

Merci d'avance pour toute aide sur les pages blanche...

JojoSs
Oui ce code fonctionne sous Safari (il s'agit d'un transformation coté client!) et sur Mac. Ne disposant pas de Windows je ne peux pas vous en dire plus. Sinon que sous Firefox Mac, ça ne marche pas non-plus. Je m'en suis sorti, mais je ne me souviens plus trop comment, et bien des semaines plus tard pour que ça marche sous FF Mac. Ça dépend du processeur XSLT employé. Même coté serveur avec php ça dépendra du processeur (Sablotron, Xalan, Saxon ou Libxslt) que j'avais testés avec l'application TestXSLT. Mais je ne me souviens plus lequel fonctionnait! Libxslt je crois ...

Si j'ai le temps demain je regarderai ça, il est tard.

(mon code final est plus complexe que celui que j'avais montré ici pour trouver de l'aide, je ne peux pas vous le donner comme ça sans le simplifier un peu!)

Vous allez faire une transformation coté client ou serveur? Et si c'est sur le serveur, quelle technologie allez-vous employer?
Bonjour,

Et merci de la reponse.

A vrais dire c'etait plus pour une aplication client (Une gestion de document sous DVD ou intranet)

Ma premier idée est plus tourner vers un menu qui sera icrémenter sur un DVD de documentation personnel)

Merci