Précédent   Forum des professionnels en informatique > Autres langages > XML/XSL et SOAP
XML/XSL et SOAP Forum d'entraide sur XML et SOAP. Avant de poster -> FAQ XML, Sources XML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 11/06/2003, 00h22   #1
Rédacteur/Modérateur
 
Avatar de Erwy
 
Homme erwan
Développeur Web
Inscription : novembre 2003
Messages : 4 980
Détails du profil
Informations personnelles :
Nom : Homme erwan
Âge : 35
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur Web
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2003
Messages : 4 980
Points : 8 021
Points : 8 021
Par défaut Contribuez à la FAQ et aux CODES SOURCE XML

La FAQ XML est disponible ici:
http://xml.developpez.com/faq/


Afin de continuer à la faire évoluer mais aussi afin de pouvoir publier de nouveaux CODES SOURCES nous avons toujours besoin de votre aide.

Vos contributions doivent être rédigées clairement dans un français correct. Les réponses peuvent inclure du code, des images, des fichiers joints, des liens internes ou externes à Développez.com et des références à d'autre questions/réponses de la FAQ ou des CODES SOURCES.


Merci pour votre participation à la vie du forum XML !
Erwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/06/2003, 14h56   #2
Rédacteur
 
Avatar de grishka
 
Inscription : janvier 2003
Messages : 288
Détails du profil
Informations forums :
Inscription : janvier 2003
Messages : 288
Points : 409
Points : 409
Par défaut variable xsl/xslt

je propose de rappeler sommairement ce qu'est xml, xsl, un schema xml, une dtd, xpath, soap, etc... un peu comme la faq java.


coté xsl, voici les questions que j'ai souvent rencontré :

Q: comment incrémenter une variable ?
R: En xsl, les variables n'existent pas. XSL est un langage purement fonctionnel et déclaratif, donc sans effet de bord, contrairement à un langage procédural comme le C. D'ou l'impossibilité de définir des variables globales. En effet une règle de transformation ne doit dépendre que de ses arguments et de sa définition. Le mot clé xsl:variable ne définit pas en réalité une variable mais une constante.

La conséquence d'un programme basé sur un langage fonctionnel comme xsl est qu'il ne peut pas garder d'état. Donc on est obligé de recalculer à chaque fois une information si elle apparaît plusieurs fois. On a donc un langage robuste qui en contrepartie peut aboutir sur des performances assez faibles.

La solution est donc soit d'utiliser les fonctions xpath, soit d'implémenter ses propres fonctions récursives

Q: comment calculer des numéros de paragraphes dans un document ?
R: on utilise la fonction xpath position() qui renvoie la position d'un noeud paragraphe dans le noeud parent

Q: comment calculer une somme de valeurs situées dans des noeuds?
R: on utilise la fonction xpath sum(...)

Code :
1
2
3
4
5
6
7
8
9
10
<a>
<b>10</b>
<b>50</b>
<b>30</b>
<b>10</b>
</a>
 
<xsl:template match="a">
  <xsl:value-of select="sum(b)"/>
</xsl:template>

Q: comment calculer le total d'une commande?
R: les fonctions xpath ne me permette pas d'effectuer un traitement sur mes données.Il faut définir un templates nommés récursif.
Avec XSL on peut définir des règles de transformation des noeuds (templates), mais aussi des templates indépendants des noeuds que l'on appeler n'importe ou. Ils sont équivalents à des fonctions.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
<commande>
<produit><nb>1</nb><prix>10</prix></produit>
<produit><nb>2</nb><prix>50</prix></produit>
<produit><nb>1</nb><prix>80</prix></produit>
<produit><nb>3</nb><prix>20</prix></produit>
</commande>
 
<xsl:template name="calcul_total">
   <xsl:param name="total"/> 
   <xsl:param name="position"/> 
 
   <xsl:choose> 
     <xsl:when test="$position <= count(produit)"> 
       <xsl:variable name="prixl"><xsl:value-of select="produit[position()=$position]/prix"/></xsl:variable> 
       <xsl:variable name="nbl"><xsl:value-of select="produit[position()=$position]/nb"/></xsl:variable> 
 
       <xsl:call-template name="calcul_total"> 
         <xsl:with-param name="total"><xsl:value-of select="$total+$prixl * $nbl"/></xsl:with-param> 
         <xsl:with-param name="position"><xsl:value-of select="$position+1"/></xsl:with-param> 
            </xsl:call-template> 
        </xsl:when> 
        <xsl:otherwise> 
           <xsl:value-of select="$total"/>
        </xsl:otherwise>
</xsl:choose>
</xsl:template>
 
<xsl:template match="commande">
<xsl:call-template name="calcul_total"> 
   <xsl:with-param name="total">0</xsl:with-param> 
   <xsl:with-param name="position">1</xsl:with-param> 
</xsl:call-template>
</xsl:template>
non c'est pas lourd du tout ! mais en attendant xpath 2.0 c'est probablement la seule facon de faire!
__________________
"Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
--Scott Adams
grishka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/06/2003, 11h41   #3
Rédacteur
 
Avatar de grishka
 
Inscription : janvier 2003
Messages : 288
Détails du profil
Informations forums :
Inscription : janvier 2003
Messages : 288
Points : 409
Points : 409
Par défaut passage de paramètres- transformation serveur

Q: comment passer des paramètres à une feuille XSLT?

R: La solution consiste à utiliser un processeur Xslt auquel on passe les paramètres souhaités.

Côté serveur

il suffit d'écrire un script qui récupère les paramètres de la requête http, invoque le processeur xslt avec ces paramètres puis écrit le résultat dans la réponse http.

-PHP : Sablotron
-JAVA : JAXP (Java), Xalan (Apache)
-C++ : Xalan C++ (Apache)
-ASP/DotNet : composants MsXML ou XMLDOM

Coté Client :


Malheureusement la balise xml-stylesheet ne permet pas de passer deq paramètres à une feuille de style...

Une astuce permet cependant de modifier les éléments de la feuille xslt avant la transformation en accédant au document xsl lié (avec l'api Dom de javascript), mais cette solution n'est pas vraiment pas recommandée.

Une solution consiste à écrire un code javascript qui va :
-charger les document xml et la feuille de style
-créer un processeur Xslt en lui fournissant la feuille de style
-passer les paramètres éventuels de la feuille de style
-écrire le résultat dans un élément de la page.

IE et Mozilla/Firefox n'ont pas la même API de transformation XSLT.

Exemple de page effectuant un tri dynamique sur des données XML.


test.html
: page html effectuant la transfo

Pour IE :

Attention il vous faudra la librairie MsXML 4.0

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>
   <head>
      <script type="text/javascript">
        function tri(field,order) {
            var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0"); 
            var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0"); 
            var xslProc; 
            xslDoc.async = false; 
            xslDoc.load("test-xslt.xml"); 
            xslt.stylesheet = xslDoc; 
            var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.4.0"); 
            xmlDoc.async = false; 
            xmlDoc.load("test.xml"); 
            xslProc = xslt.createProcessor(); 
            xslProc.input = xmlDoc; 
            xslProc.addParameter("field", field); 
            xslProc.addParameter("order", order); 
            xslProc.transform(); 
            document.body.innerHTML=xslProc.output;
        }
      </script>
   </head>
   <body>
      <script type="text/javascript">
        tri('name', 'ascending');
      </script>
   </body>
</html>
Pour Mozilla/Firefox:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
<html>
   <head>
      <script type="text/javascript">
                var processor;
            var xslt;
            var xmlDoc;
 
                function tri(field,order) {
                    processor.setParameter(null,"field", field);
                    processor.setParameter(null,"order", order);
                    var resultat = processor.transformToFragment(xmlDoc,document);
                   document.body.innerHTML = ""
                    document.body.appendChild(resultat);
                }
 
                function tri_init(field,order) {
                    xslt= document.implementation.createDocument("", "", null);
                    xslt.async=false;
                    xslt.load("test-xslt.xml");
 
                    processor =new XSLTProcessor();
                    processor.importStylesheet(xslt);
                    xmlDoc= document.implementation.createDocument("", "", null);
                    xmlDoc.async=false;
                    xmlDoc.load("test.xml");
 
                                tri(field,order);
                }
      </script>
   </head>
   <body>
      <script type="text/javascript">
        tri_init('name', 'ascending');
      </script>
   </body>
</html>
test-xslt.xml
feuille xslt des règles de transfo

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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" indent="yes"/>
 
    <xsl:param name="field"/>
    <xsl:param name="order"/>
 
    <xsl:template match="persons">
        <table>
        <xsl:variable name="neworder">
          <xsl:if test="$order='ascending'">descending</xsl:if>
          <xsl:if test="$order='descending'">ascending</xsl:if>
         </xsl:variable>
 
           <tr><th><a href="javascript:tri('name','{$neworder}')">name</a></th><th><a href="javascript:tri('phone','{$neworder}')">phone number</a></th></tr>
         <xsl:for-each select="person">
          <xsl:sort select="*[name()=$field]" order="{$order}"/>
           <tr><td><xsl:value-of select="name"/></td><td><xsl:value-of select="phone"/></td></tr>
         </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>
test.xml

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
  <name>
    toto
  </name>
  <phone>
      1122334455
  </phone>
</person>
<person>
  <name>
    titi
  </name>
  <phone>
      3344556677
  </phone>
</person>
<person>
  <name>
    tata
  </name>
  <phone>
      2233445566
  </phone>
</person>
</persons>
__________________
"Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
--Scott Adams
grishka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/08/2003, 01h46   #4
Membre confirmé
 
Inscription : mars 2002
Messages : 241
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 241
Points : 206
Points : 206
Q: Hé euh ... avec PHP ?
R: Ben, ou utilise la fonction xslt_process.

Perso, j'ai deux fichiers include :

1) xslt.inc : Fixe les variables communes à un répertoire
Code :
1
2
3
4
5
6
<?
  // Paramètres pour la feuille XSLT
  $racine = '';
  $repertoire = '';
  include ("xslt_html.inc");
?>
2) xslt_html.inc : Appel le processeur XSLT pour générer du HTML
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?
$est_en_ligne = 1;  // Est-ce qu'on est en ligne ?
$xsl = "xsl/html.xsl"; // Feuille de style XSLT utilisée ?
$motcle = implode($motcle, ", "); // Concatène les mots-clés avec des virgules
 
// Paramètres pour la feuille de style XSLT
$param_xslt = Array
(
  'page'       => $page,
  'racine'     => $racine,
  'repertoire' => $repertoire,
  'est_en_ligne' => $est_en_ligne,
  'motcle' => $motcle
  // rajoutez vos paramètres XSLT
);
 
//----------------------------------------------------------------------------
 
// Evalue le code PHP si le document XML en possède (variable $php)
$xml = file($racine."xml/".$repertoire.$page.".xml");
if (isset($php))
{
  // Extrait la première balise "(?xml ... ?)" (entre crochets)
  $entete_xml = array_shift($xml);
  ob_start();
  eval(" ?".">".implode ('', $xml)."<"."?php ");
  $xml = ob_get_contents();
  ob_end_clean();
  $xml = $entete_xml . $xml;
} else {
  $xml = implode ('', $xml);
}
 
// Paramètres pour Sablotron (processeur XSLT)
$param_sablotron = Array
(
  '/_xml' => $xml
);
 
//----------------------------------------------------------------------------
 
// Crée le processeur XSLT
$xh = xslt_create();
$nom_fich = 'file://' . getcwd () . '/' . $racine;
xslt_set_base ($xh, $nom_fich);
 
// Traite le document
$result = xslt_process($xh, 'arg:/_xml', $xsl, NULL, $param_sablotron, $param_xslt);
if (!$result)
{
  echo ("<p>Erreur lors du traitement du fichier "'.$page.'.xml" ');
  echo ('par la feuille de style XSL "'.$xsl.' :<br />');
  echo (xslt_error($xh));
  echo ('</p>');
  // todo : afficher le contenu de $xml
  die();
}
 
// Ecrit le résultat dans le flux HTML
echo ($result);
 
// Détruit le processeur XSLT
xslt_free($xh);
?>
Si la variable $php est définie ($php=true), alors le fichier XML est entièrement évalué avec d'être passé au processeur XSLT.

Finalement, ça s'utilise donc comme ça :
(index.php)
Code :
1
2
3
4
5
6
<?
  $page = "index";
  $motcle = Array("un", "deux");
  // $php = true;
  include ("xslt.inc");
?>
C'est assez simple d'utilisation, non ? Niveau organisation :

répertoire racine : les fichiers PHP (index.php)
répertoire xsl/ : les feuilles XSLT (html.xsl)
répertoire xml/ : les documents XML (index.xml)

@+ Haypo
haypo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2004, 09h06   #5
Rédacteur/Modérateur
 
Avatar de Erwy
 
Homme erwan
Développeur Web
Inscription : novembre 2003
Messages : 4 980
Détails du profil
Informations personnelles :
Nom : Homme erwan
Âge : 35
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur Web
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2003
Messages : 4 980
Points : 8 021
Points : 8 021
Par défaut Re: variable xsl/xslt

Citation:
Envoyé par Grégory Picavet
Q: comment calculer le total d'une commande?
R: les fonctions xpath ne me permette pas d'effectuer un traitement sur mes données.Il faut définir un templates nommés récursif.
Avec XSL on peut définir des règles de transformation des noeuds (templates), mais aussi des templates indépendants des noeuds que l'on appeler n'importe ou. Ils sont équivalents à des fonctions.

<commande>
<produit><nb>1</nb><prix>10</prix></produit>
<produit><nb>2</nb><prix>50</prix></produit>
<produit><nb>1</nb><prix>80</prix></produit>
<produit><nb>3</nb><prix>20</prix></produit>
</commande>

j'utilise cette methode,un avis?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method = "html" encoding="Windows-1252" />
 
	<xsl:template match="/">	
		<html>
			<title></title>
			<body>
 
 
			<xsl:call-template name = "total" >
				<xsl:with-param name="noeuds" select="//produit"></xsl:with-param>
				<xsl:with-param name="s_total" select="0"></xsl:with-param>
			</xsl:call-template>
 
			</body>
		</html>
	</xsl:template>
 
	<xsl:template name="total">
	<xsl:param name="noeuds" />
	<xsl:param name="s_total" />
 
 
	<xsl:choose>
		<xsl:when test="$noeuds[position()&gt;1]">
		<xsl:call-template name = "total" >
				<xsl:with-param name="noeuds" select="$noeuds[position()&gt;1]"></xsl:with-param>
				<xsl:with-param name="s_total" select="$s_total+(number($noeuds[1]/nb)*number($noeuds[1]/prix))"></xsl:with-param>
			</xsl:call-template>
		</xsl:when>
 
		<xsl:otherwise>
		 total:
		 <xsl:value-of select="$s_total+(number($noeuds[1]/nb)*number($noeuds[1]/prix))" />
		</xsl:otherwise>
	</xsl:choose>
 
	</xsl:template>
 
 
 
</xsl:stylesheet>
__________________
modérateur/rédacteur XML
Je ne reponds pas aux questions par MP

Quand une réponse vous a été utile, pensez à utiliser le nouveau système de notation
Erwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2005, 14h01   #6
Rédacteur
 
Avatar de Swoög
 
Inscription : janvier 2003
Messages : 6 053
Détails du profil
Informations personnelles :
Âge : 24

Informations forums :
Inscription : janvier 2003
Messages : 6 053
Points : 7 144
Points : 7 144
Envoyer un message via MSN à Swoög Envoyer un message via Skype™ à Swoög
Je proposerais également de rappeler la différence en tre "bien-formé" et "valide", car ce sont deux notions de bases en XML, qui sont parfois mal différenciées par les nouveaux :

Citation:
il est important surtout en XML de bien connaître la différence entre "bien-formé" et "valide"

un doc XML bien formé, est un doc qui respecte certains règles de bases de XML :

toutes balise ouvertes est refermée,
tout attribut a une valeur
toute valeur d'attribut est entre quotes (simples ou doubles)
les balises sont fermées selon le principe LIFO (Last In, First Out : càd si les balises sont ouvertes dans l'ordre <a><b><c>, elle doivent être refermé dans l'ordre inverse : </c></b></a>)
les noms de balises et noms et valeurs d'attributs sont sensibles à la casses,
tous les "méta-caractères" XML tels que <, &, etc... sont échapés grâce aux entitées générales (&lt; pour <; &amp; pour & ....)
un nom de balise ne commence pas par un chiffre et ne contient pas d'espace, etc, etc, etc... (voir la recommendation du W3C pour une liste exhaustive )


un doc XML Valide, n'est pas valide en lui-même (alors que la bien formation d'un doc ne repose que sur le doc en lui-même), il est valide par rapport à une définition de structure (DTD, XML Schema, ...), il est valide, s'il respect la structure définie par cette définition de structure (càd, imbriquement des balises, attributs présents sur les balises, valeurs des attributs, contenu des balises, etc...)

un doc XML peut tout à fait être bien formé, et ne pas être valide s'il n'est relié à aucune définition de structure, ce qui n'empêche pas son exploitation.

En revanche, quelque soit la définition de structure, et quelque soit le format de cette définition (DTD, XML Schema, etc...) un document mal-formé, ne sera jamais valide !
Je suis prêt, si ce rajout est fait à la FAQ, de retravailler la liste des condition à la bien formation d'un document afin de la rendre exhaustive, si besoin est, me contacter par MP, Merci d'avance !
Swoög est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2005, 15h56   #7
Membre Expert
 
Avatar de virgul
 
Inscription : novembre 2004
Messages : 1 624
Détails du profil
Informations personnelles :
Âge : 28

Informations forums :
Inscription : novembre 2004
Messages : 1 624
Points : 1 498
Points : 1 498
Envoyer un message via MSN à virgul Envoyer un message via Skype™ à virgul
Salut l'équipe,

Voila moi deux trucs qui me parait très intéressant a mettre dans la faq c'est:

Q1: comment faire un tri variable dans un for-each?

Q2:Comment appeler x fois le même template avec des conditions différentes?

R1: Ce n'est pas possible (car sort doit être fils de for-each et peu de ce fait pas se trouver dans un if ou un choose en-dessous) il faut passer par un apply-templates et faire un choose afin de définir le tri qu'on veux obtenir:

Soit:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
<xsl:choose>
<xsl:when test="$Sort=1">
<xsl:apply-templates select="Personal/Person">
<xsl:sort order="ascending" data-type="number" select="FonctionNR"/>
<xsl:sort order="ascending" data-type="text" lang="fr" select="Nom"/>
</xsl:apply-templates>			
</xsl:when>
<xsl:when test="$Sort=2">
<xsl:apply-templates select="Personal/Person">
<xsl:sort order="ascending" data-type="text" lang="fr" select="Nom"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="Personal/Person"/>
</xsl:otherwise>
</xsl:choose>
Donc si la variable Sort=1 : tri par numéro de fonction (1 en premier et après les autre) a noté que si pas de fonctionnr les noeud concerner seront les premier car ascending. Et après par ordre alphabétique si la fonctionnr est la même.

si Sort=2 tri par nom seuleument

si Sort n'est pas égal à 2, 3 ou il est manquant : pas de tri!


R2: il suffit de faire dans l'apply-template un appel avec le condition et dans le xsl:template sans les condition

Soit:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
<xsl:choose>
<xsl:when test="$Sort=1">
<xsl:apply-templates select="Personal/Person[($Validonly = 0 or ($Validonly = 1 and @valid = '1')) and Eigenschaft/@EigNr]"/>
</xsl:apply-templates>			
</xsl:when>
<xsl:when test="$Sort=2">
<xsl:apply-templates select="Personal/Person[($Validonly = 0 or ($Validonly = 1 and @valid = '1')) and not(Eigenschaft/@EigNr)]"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="Personal/Person"/>
</xsl:otherwise>
</xsl:choose>
<xsl:template match="Personal/Person"/>
...
...
Tous appel le même template mais avec des conditions différentes


et maintenant si on veux par exemple faire un tri en fonction du fonctionnr et si il n'y en a pas les mettre a la fin on combine les deux et ca nous donne:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xsl:choose>
<xsl:when test="$Sort=1">
<xsl:apply-templates select="Personal/Person[($Validonly = 0 or ($Validonly = 1 and @valid = '1')) and Eigenschaft/@EigNr]">
<xsl:sort order="ascending" data-type="number" select="fonctionnr"/>
<xsl:sort order="ascending" data-type="text" lang="fr" select="nom"/>
</xsl:apply-templates>
<xsl:apply-templates select="Personal/Person[($Validonly = 0 or ($Validonly = 1 and @valid = '1')) and not(Eigenschaft/@EigNr)]">
<xsl:sort order="ascending" data-type="number" select="ZeichnungsArt/@ZartNr" lang="fr"/>
<xsl:sort order="ascending" data-type="text" lang="fr" select="Personalien/PersDaten"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="Personal/Person"/>
</xsl:otherwise>
</xsl:choose>
Si Sort=1: on fait la boucle avec tous ceux qui on ont un et on le trie par fonction et nom puis on fais le même template mais avec ceux qui n'ont pas de fonction et on les trie par nom.

Si Sort!=1 ou inexistant : pas de tri

J'espère que ca vous sera autant utile qu'a moi!!!

++

Thierry
virgul est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2005, 14h25   #8
Membre éprouvé
 
Avatar de Perceval
 
Homme
Responsable de projet fonctionnel
Inscription : mars 2003
Messages : 355
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Royaume-Uni

Informations professionnelles :
Activité : Responsable de projet fonctionnel
Secteur : Distribution

Informations forums :
Inscription : mars 2003
Messages : 355
Points : 436
Points : 436
Envoyer un message via ICQ à Perceval
A mon tour d'essayer d'alimenter la FAQ et les trucs et astuces.

Problématique : J'ai eu à réaliser un site intranet, hébergé sur un serveur qui ne tolére que les langages HTML, Javascript et XML. Cependant, je voulais à tout pris ne pas utiliser les frames et essayer d'adopter le système des pseudo frames dont je me sers souvent en PHP. Mais voila, comment faire pour transmettre en paramètres des variables autrement que via l'URL ? Et indiquer au navigateur la page à afficher en fonction du lien cliqué dans le menu.
Habituellement, je me sers de la fonction switch de php, mais celle ci n'existe pas en XSLT. Du coup, je me suis servi de <xsl:choose> pour la remplacer.

Ma solution

Fichier XML (index.xml) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="index_transfo.xsl"?>
 
<index page="index">
 
 <article>
  <texte>
   <para>
    Nulla dignissim. Aliquam laoreet rhoncus tellus. Sed malesuada. Proin nibh arcu, vulputate ut,
    imperdiet sodales, convallis sit amet, nulla. Cras tincidunt eros quis mauris. Integer at dui
    non libero luctus consequat. Nunc vehicula mattis nulla. Sed venenatis consectetuer risus. 
    Donec nisl massa, dignissim a, porttitor ut, condimentum ut, est. Ut ullamcorper feugiat sem. 
    Vestibulum vestibulum mi et turpis.
   </para>
   <para>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque pede. Maecenas urna diam, 
    egestas in, lacinia vel, condimentum quis, lorem. Duis consequat dolor quis tortor. Nullam 
    nonummy vestibulum leo. Nulla lorem libero, gravida at, interdum sed, laoreet id, risus.
    Integer consequat. Aliquam vulputate consectetuer quam.
   </para>
  </texte>
 </article>
 
</index>
Une 2ème fichier XML (actualites.xml) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="index_transfo.xsl"?>
 
<actu page="actualites">
 
 <article id="1">
  <titre id="1">titre du 1er article</titre>
  <date>14/07/2004</date>
  <texte>
   <para>
    Nulla dignissim. Aliquam laoreet rhoncus tellus. Sed malesuada. Proin nibh arcu, vulputate ut,
    imperdiet sodales, convallis sit amet, nulla. Cras tincidunt eros quis mauris. Integer at dui
    non libero luctus consequat. Nunc vehicula mattis nulla. Sed venenatis consectetuer risus. 
    Donec nisl massa, dignissim a, porttitor ut, condimentum ut, est. Ut ullamcorper feugiat sem. 
    Vestibulum vestibulum mi et turpis.
   </para>
  </texte>
 </article>
 
 <article id="2">
  <titre id="2">titre du 2eme article</titre>
  <date>02/04/2005</date>
  <texte>
   <para>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
    Mauris enim eros, auctor eu, facilisis ut, bibendum a, sem. Ut congue metus sit amet enim. 
    Proin pulvinar, sapien in auctor auctor, dolor erat tempus nibh, sed tincidunt nulla quam a 
    libero. Pellentesque massa eros, varius vel, pellentesque a, iaculis at, massa. Duis lobortis 
    placerat lorem. Cras facilisis, augue et lacinia interdum, pede arcu molestie elit, sed 
    tincidunt dolor urna id pede. Aliquam eu nisl non est commodo faucibus.
   </para>
  </texte>
 </article>
 
</actu>
Fichier XSL (index_transfo.xsl) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="html" indent="yes"/>
 
<xsl:template match="/">
 <html>
  <head>
   <link rel="stylesheet" type="text/CSS" href="xmlindex.css"/>
   <style type="text/css" media="screen">
    p {margin:5px; text-align:justify; text-indent:10px; }
    #menu { border:1px solid #000; width:150px; float:left; }
    #conteneur { float:left; border:1px solid #000; width:60%; margin:0 20px;}
    .spacer { clear:both; }
   </style>
  </head>
 
  <body>
 
  <div id="general">
 
<div id="menu">
 <ul>
  <li><a href="index.xml">Accueil</a></li>
  <li><a href="actualites.xml">Actualités</a></li>
 </ul>
</div> <!-- fin du div menu -->
 
  <div id="conteneur">
 
   <div id="contenu">
    <xsl:call-template name="recup_page"/>
 
   </div> <!-- fin du div contenu -->
  <div class="spacer"> </div>
 
 
  </div> <!-- fin du div conteneur -->
 
  </div> <!-- fin du div general --> 
  </body>
 </html>
</xsl:template>
 
 
<!--
    *******************************************************************
    ***  Template qui permet d'afficher la page en fonction du lien ***
    *******************************************************************-->
 
<xsl:template name="recup_page">
 
 <xsl:choose>
  <xsl:when test="contains(//@page, 'index')">
   <xsl:apply-templates select="document('index.xml')/index"/> 
  </xsl:when>
 
  <xsl:when test="contains(//@page, 'actualites')">
   <xsl:apply-templates select="document('actualites.xml')/actu"/> 
  </xsl:when>  
 </xsl:choose>
</xsl:template>
 
 
<!--
    *************************************
    ***  template pour la page index  ***
    *************************************-->
 
 
<xsl:template match="index">
 <h3><xsl:value-of select="article/titre"/></h3>
 <p>
  <xsl:value-of select="article/texte/*" />
 </p>
</xsl:template>
 
 
 
<!--
    ******************************************
    ***  Template pour la page actualites  ***
    ******************************************-->
 
<xsl:template match="actu">
 
 <div id="actualites">
   <xsl:for-each select="article">
   <xsl:sort select="@id" order="descending" />
    <table>
     <tr class="titre">
      <td><xsl:value-of select="titre" /></td>
      <td class="date"><xsl:value-of select="date"/></td>
     </tr>
     <tr>
      <td colspan="2">
       <xsl:for-each select="texte/para">
        <p><xsl:value-of select="." /></p>
       </xsl:for-each>
      </td>
     </tr>
    </table>
   </xsl:for-each>
 </div>
 
</xsl:template>
 
</xsl:stylesheet>
Explication de ma méthode
Je déclare dans mon fichier xml une valeur dans un attribut qui va me servir de "variable" (ici, il s'agit de l'attribut "page"). Ensuite, en fonction de cette valeur que je récupère dans mon xsl via <xsl:choose>, j'affiche la page correspondante. Nous avons donc un pseudo-frame en XML/XSL.

Je ne sais pas si tout ceci est optimisé ou si il y'a d'autre solutions, mais c'est celle que j'ai trouvé pour résoudre mon problème.

A vos critiques....
__________________
Save a tree... Eat a beaver
Perceval est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2006, 13h36   #9
Futur Membre du Club
 
Inscription : novembre 2005
Messages : 25
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 25
Points : 15
Points : 15
Par défaut Re: passage de paramètres- transformation serveur

Ceci est un complément à l'article :
http://www.developpez.net/forums/vie...=454740#454740

Citation:
Envoyé par Grégory Picavet
Q: comment passer des paramètres à une feuille XSLT?
Je voulais ajouter :
1/ La solution Javascript énoncée là ne fonctionne malheureusement pas avec FireFox. J'ai donc opté pour une solution en php.
(c'est a dire une modifiaction coté serveur)

2/Dans mon fichier xml, j'avais des attribus au lieu de d'éléments fils
Code :
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<persons>
  <person name="toto" phone="1122334455" />
  <person name="titi" phone="3344556677" />
  <person name="tata" phone="2233445566" />
</persons>
il faut alors remplacer
Code :
<xsl:sort select="*[name()=$field]" order="{$order}"/>
par
Code :
<xsl:sort select="@*[name()=$field]" order="{$order}"/>
(c'est peut être évident, mais j'ai du chercher longtemps!!)

[Grégory PICAVET le 21/04/2006 :
J'ai mis à jour le tri côté client pour Mozilla/Firefox
]
Caille Rotie est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2006, 14h39   #10
Expert Confirmé
 
Avatar de trotters213
 
Inscription : janvier 2005
Messages : 2 572
Détails du profil
Informations personnelles :
Âge : 26
Localisation : France, Gard (Languedoc Roussillon)

Informations forums :
Inscription : janvier 2005
Messages : 2 572
Points : 2 605
Points : 2 605

Après avoir bataillé, j'ai trouvé comment utiliser des variables XSL dans du code SVG (je pense être à la limite de la FAQ XML/XSL et SOAP mais je propose quand même ).

Question Comment utiliser des variables XSL dans du code SVG ?

Réponse Il suffit de rajouter des accolades autour de la variables XSL.

Exemple :
Code :
1
2
3
<svg>
 <rect x="{$largeur}" y="{$hauteur}" width="50" height="50"/> 
</svg>
$largeur et $hauteur étant 2 variables XSL.

C'est bête comme tout mais j'ai cherché la solution longtemps sur le net en vain et personne sur le forum n'a été capable de me répondre(je suppose, plutôt, que la plupart des personnes ont trouvé la question trop simple et dépourvu d'intérêt ).
Donc voilà.
__________________
Pensez au tag
Les règles du Forum

Dev. Web : FAQ (X)HTML/CSS | Tutos (X)HTML | Tutos CSS

PHP : FAQ PHP | Tutos PHP | Benchmark PHP 5

SQL : Cours SQL
trotters213 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/04/2006, 22h03   #11
Rédacteur/Modérateur
 
Avatar de Erwy
 
Homme erwan
Développeur Web
Inscription : novembre 2003
Messages : 4 980
Détails du profil
Informations personnelles :
Nom : Homme erwan
Âge : 35
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur Web
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2003
Messages : 4 980
Points : 8 021
Points : 8 021
La première version FAQ XML est desormais disponible ici:
http://xml.developpez.com/faq/


Afin de continuer à la faire évoluer mais aussi afin de pouvoir publier prochainement les codes sources XSLT nous avons toujours besoin de votre aide.


Je souhaite préciser que nous avons notament besoin sur les informations concernant la validation d'un fichier XML reposant sur un XML Schema, nous attendons vos contributions : Comment valider un XML avec un XSD ?
__________________
modérateur/rédacteur XML
Je ne reponds pas aux questions par MP

Quand une réponse vous a été utile, pensez à utiliser le nouveau système de notation
Erwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/05/2007, 16h35   #12
Invité de passage
 
Inscription : mai 2007
Messages : 1
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 1
Points : 1
Points : 1
Par défaut xsl:sort paramétré fonctionnant avec Opera

La commande :
<xsl:sort select="*[name()=$field]" case-order="upper-first" data-type="text" order="{$order} />

ne fonctionne pas avec Opera, la valeur de $order n'est pas prise en compte.

Cette instruction fonctionne corectement sous IE, Mozilla, FireFoxe, Netscape, SeaMonkey, GranParadiso

Le contournemt pour obtenir un fonctionnement identique ets le suibant :

<xsl:if test="$order='ascending'">
<xsl:apply-templates select="DMC">
<xsl:sort select="*[name()=$field]" case-order="upper-first" data-type="text" order="ascending" />
</xsl:apply-templates>
</xsl:if>
<xsl:if test="$order='descending'">
<xsl:apply-templates select="DMC">
<xsl:sort select="*[name()=$field]" case-order="upper-first" data-type="text" order='descending' />
</xsl:apply-templates>
</xsl:if>
ErickDenis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2008, 20h52   #13
Rédacteur
 
Avatar de gege2061
 
Inscription : juin 2004
Messages : 5 850
Détails du profil
Informations personnelles :
Âge : 28
Localisation : France, Indre et Loire (Centre)

Informations forums :
Inscription : juin 2004
Messages : 5 850
Points : 8 299
Points : 8 299
Par défaut [XPath] Rechercher un alément à partir de son contenu

Bonjour,

J'ai pas mal galèré pour trouver la solution à un problème qui paraît plutôt simple :

Citation:
Comment sélectionner un noeud grâce à son contenu !

Si vous souhaiter recherche le contenu exact du noeud, il faut utiliser le caractère point '.' qui représente la valeur textuelle en cours de lecture. Exemple :
Code :
/project/files/file[.='main.vala']
Ce qui donne :
Code :
1
2
3
4
5
6
7
8
9
10
11
<?version="1.0" encoding="UTF-8"?>
<project>
  <name>test</name>
  <files>
    <file>main.vala</file>
    <file>old_main.vala</file>
  </files>
  <compiler>
    <pkg>gnome</pkg>
  </compiler>
</project>
Ou si vous souhaitez rechercher un noeud contenant une chaîne :
Code :
/project/files/file[contains(string(),'main.vala')]
Code :
1
2
3
4
5
6
7
8
9
10
11
<?version="1.0" encoding="UTF-8"?>
<project>
  <name>test</name>
  <files>
    <file>main.vala</file>
    <file>old_main.vala</file>
  </files>
  <compiler>
    <pkg>gnome</pkg>
  </compiler>
</project>
Ce qui correspond à rechercher *main.vala*
En espérant que la réponse n'a pas été postée 100 fois sur le forum

[edit]Corrigé grâce aux précieux conseils d'Erwy, merci[/edit]
__________________
gege2061's blog
gege2061 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 14h32.


 
 
 
 
Partenaires

Hébergement Web