IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XSL/XSLT/XPATH XML Discussion :

[XSLT] Test dynamique


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut [XSLT] Test dynamique
    Bonjour,
    Je voudrais faire quelque chose mais je ne sais absolument pas comment m'enligner...

    Je voudrais faire un xsl qui pourrait recevoir n critères de filtre...

    Comme je ne sais pas combien de critère je vais recevoir d'une fois à l'autre, je voudrais monter dynamiquement le test de mon <xsl:for-each>.

    Alors bon, j'avais eu l'idée de passer en paramètre à ma xsl chaîne déjà formatée et faire exécuter le test mais le test ne veut pas traiter ma chaîne comme étant le test lui même...

    Je sais plus là!!!

    AIDEZ MOIIIIIIII !!!



    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    c'est une question récurrente : comment faire évaluer par XSLT une expression XPath contenue dans une chaîne ? La réponse est sans appel : on peut pas ! Par contre, si tes critères de filtre suivent un formalisme précis, alors il peut exister des solutions. Expose ton projet.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  3. #3
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Ok, en fait, je construit un datagrid. dans mes entêtes, j'ai un bouton filtre qui permet à l'utilisateur de choisit une ou plusieurs valeur qui peut se retrouver dans le champ sélectionné. Par exemple, pour la colone langue, si le tableau contient EN, FR, SP, l'utilisateur pourra sélectionner EN et SP seulement. Mais il pourrait tout aussi bien sélectionne uniquement FR.

    Maintenant, je peux le faire sur un critère en utilisant ce code que tu as probablement déjà vu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    item[child::*[name()=$filterKey and text()=$filterValue]]
    et ça fonctionne très bien. Ce que je voudrais, ça serait, en fonction du nombre de paramètre voir le même type de requète mais en ayant plusieurs fois le test et les séparer pas de "or" qui me donerait en absolu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    item[child::*[(name()=$filterKey and text()=$filterValue) or (name()=$filterKey2 and text()=$filterValue2)]]
    Je sais pas si tu comprend...
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  4. #4
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    J'avais fait a une epoque une feuille xslt dont les tris, bien que connus(dans le sens on connait les balises qui peuvent être triées) étaient tous "optionnels".Mais bon, pas particulierement simple et je ne suis pas sur que ca corresponde a ton probleme

    http://www.developpez.net/forums/vie...&highlight=key

  5. #5
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    hummm... Ouais, c'est pas exactement ça effectivement mais j'aime bien le key que je ne connaissais pas!

    Bon, merci de ton aide, je vais continuer à essayer de trouver une solution et je vais arrêter de m'acharner à faire évaluer une chaîne!

    Merci

    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  6. #6
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    je suis bete, mais si je le comprends bien,ton probleme est tres simple si tu peux passer des noeuds en parametres
    par exemple en javascript tu peux passer un selectnodes en parametre.
    En effet on peut appliquer un xpath sur ce type de donner

    Imaginons un param noeud qui contient la selection
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    <langue>FR</langue>
    <langue>EN</langue>
    tu peux faire un apply-templates du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:apply-templates select="mes_noeuds[le_truc_langue)=$noeud/*]"/>

  7. #7
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Une solution possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <test>
    	<personne>
    		<nom>DUPONT</nom>
    		<prenom>Jean</prenom>
    		<pays>FR</pays>
    	</personne>
    	<personne>
    		<nom>DURAND</nom>
    		<prenom>Paul</prenom>
    		<pays>FR</pays>
    	</personne>
    	<personne>
    		<nom>SMITH</nom>
    		<prenom>John</prenom>
    		<pays>US</pays>
    	</personne>
    	<personne>
    		<nom>GOMEZ</nom>
    		<prenom>Pedro</prenom>
    		<pays>ES</pays>
    	</personne>
    	<personne>
    		<nom>DOUGLAS</nom>
    		<prenom>Jean</prenom>
    		<pays>US</pays>
    	</personne>
    </test>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     
    	<xsl:param name="filterKeys" select="'pays prenom '"/>
    	<xsl:param name="filterValues" select="'FR Jean '"/> 
     
    	<xsl:template match="/">
    		<resultat>
    			<xsl:call-template name="filter">
    				<xsl:with-param name="filterKeys" select="$filterKeys"/>
    				<xsl:with-param name="filterValues" select="$filterValues"/>
    				<xsl:with-param name="items" select="test/personne"/>
    			</xsl:call-template>
    		</resultat>
    	</xsl:template>
     
    	<xsl:template name="filter">
    		<xsl:param name="items"/>
    		<xsl:param name="result" select="/.."/>
    		<xsl:param name="filterKeys"/>
    		<xsl:param name="filterValues"/>
    		<xsl:variable name="key" select="substring-before($filterKeys, ' ')"/>
    		<xsl:variable name="value" select="substring-before($filterValues, ' ')"/>		
    		<xsl:choose>
    			<xsl:when test="$key != '' and $value != ''">
    				<xsl:call-template name="filter">
    					<xsl:with-param name="items" select="$items"/>
    					<xsl:with-param name="result" select="$result | $items[*[name() = $key and . = $value]]"/>
    					<xsl:with-param name="filterKeys" select="substring-after($filterKeys, ' ')"/>
    					<xsl:with-param name="filterValues" select="substring-after($filterValues, ' ')"/>					
    				</xsl:call-template>
    			</xsl:when>
    			<xsl:otherwise>
    				<xsl:for-each select="$result">
    					<!-- place ton traitement du résultat du filtre ici -->
    					<xsl:copy-of select="."/>
    				</xsl:for-each>
    			</xsl:otherwise>
    		</xsl:choose>
    	</xsl:template>
     
    </xsl:stylesheet>
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?xml version="1.0" encoding="UTF-8"?>
    <resultat>
    	<personne>
    		<nom>DUPONT</nom>
    		<prenom>Jean</prenom>
    		<pays>FR</pays>
    	</personne>
    	<personne>
    		<nom>DURAND</nom>
    		<prenom>Paul</prenom>
    		<pays>FR</pays>
    	</personne>
    	<personne>
    		<nom>DOUGLAS</nom>
    		<prenom>Jean</prenom>
    		<pays>US</pays>
    	</personne>
    </resultat>
    Tu passe en xsl:param les clés et les valeurs pour tes filtres (en les séparant par un espace et en n'oubliant pas l'espace de fin). Le truc qui m'ennuie le plus dans cette solution, c'est ce vilain hack :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:param name="result" select="/.."/>
    Je suis obligé d'initialiser $result avec un NodeSet vide (le noeud root ne peut pas avoir de parent), sinon $result | $items déclenche une exception car par défaut une variable vide est considérée comme de type chaîne.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  8. #8
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Wow!!! Un template récusif!!! Quelle bonne idée!!!

    Bon, je viens juste de jetter un oeil dessu, je vais prendre un p'tit 15 minutes et un café pour vraiment le comprendre mais il semble que ce soit vraiment ça!!!



    T'es un p'tit génie toi hein!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  9. #9
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Ouf!!! J'ai même été dîner pour fair passer le tout!

    Deux petites choses:

    1- Je ne comprend pas la raison d'être du <xsl:copy-of select="."/> après le traitement.

    2- Si je comprend bien, le substring-before($filterKeys, ' ') va prendre la dernière valeure mais quand tu fais ta récursive, tu envoies substring-after($filterKeys, ' ') qui devrait, si j'ai bien vu, être tout sauf la dernière... Mais je suis pas certain de bien saisir un si c'est ça que tu fais et deux comment le substring-after retournera ces valeurs...

    Merci

    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  10. #10
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par Capt. Flame
    1- Je ne comprend pas la raison d'être du <xsl:copy-of select="."/> après le traitement.
    C'est juste un exemple, pour qu'il y ait quelque chose en sortie... A toi de le remplacer par le traitement que tu veux faire sur le résultat (contenu dans $result)
    Citation Envoyé par Capt. Flame
    2- Si je comprend bien, le substring-before($filterKeys, ' ') va prendre la dernière valeure mais quand tu fais ta récursive, tu envoies substring-after($filterKeys, ' ') qui devrait, si j'ai bien vu, être tout sauf la dernière... Mais je suis pas certain de bien saisir un si c'est ça que tu fais et deux comment le substring-after retournera ces valeurs...
    Le substring-before me renvoie la clé (ou la valeur) en tête de la chaîne transmise en paramètre. Quand je fais une récursion, je passe en paramètre le reste de la chaîne, sinon ça bouclerait à l'infini sur la même valeur (la première).
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  11. #11
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Ok pour le <xsl:copy-of select="."/>, il me semblait que ça ne devait pas être là...

    Pour substring-after, je comprend, je croyais que le substring-before partait du dernier ' ' pour prendre qu la dernière valeure mais en fait, il prend du début jusqu'au ' ' et après, tu prends tout ce qui vient après pour reprendre le processus...

    Je suis quand-même un peu perdu et je veux pas faire du copier coller, je veux bien comprendre...

    Le | dans $result | $items[*[name() = $key and . = $value]]c'est la concaténation?

    Tu repasses toujours les mêmes valeures dans $items? Parce que d'une fois à l'autre, tu reçois le param et tu le repasses...

    Je ne comprends pas non plus pourquoi tu réinitialises $result à chaque passages...

    Je m'excuse, j'ai vraiment l'aire newbie mais je n'ai jamais été aussi loins dans le xsl...

    Merci de ta patience...

    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  12. #12
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Plus la peine de répondre, merci beaucoup, j'ai vraiment tout compris!!!

    T'es vraiment HOT toi!!!

    Je t'en dois une!

    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

  13. #13
    Membre habitué Avatar de Capt. Flame
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2005
    Messages : 222
    Points : 196
    Points
    196
    Par défaut
    Comme je voulais dans le cas où l'utilisateur choisit deux filtres de la même colone, je voulais que le filtre se fasse avec un "or" mais dans le cas où il choisirait un troisième filtre dans une autre colone je veux que celui-ci soit traité avec un "and"...

    Par exemple, pour reprendre ton example, Je veux les prenoms Jean et John et que le pays soit US. Le filtre traitera comme ça:

    (prenom = Jean or prenoms = John) and pays = US.

    Voici comment j'ai fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
       <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
     
       <xsl:param name="filterKeys" select="'prenom~~prenom~~pays~~'"/> 
       <xsl:param name="filterValues" select="'Jean~~John~~FR~~'"/> 
     
       <xsl:template match="/"> 
          <resultat> 
             <xsl:call-template name="filter"> 
                <xsl:with-param name="filterKeys" select="$filterKeys"/> 
                <xsl:with-param name="filterValues" select="$filterValues"/> 
                <xsl:with-param name="items" select="test/personne"/> 
             </xsl:call-template> 
          </resultat> 
       </xsl:template> 
     
       <xsl:template name="filter"> 
          <xsl:param name="items"/> 
          <xsl:param name="oldKey"/>
          <xsl:param name="result" select="/.."/> 
          <xsl:param name="filterKeys"/> 
          <xsl:param name="filterValues"/> 
          <xsl:variable name="key" select="substring-before($filterKeys, '~~')"/> 
          <xsl:variable name="value" select="substring-before($filterValues, '~~')"/>       
          <xsl:choose>
             <xsl:when test="$key != '' and $value != ''">
                <xsl:choose>
                   <xsl:when test="$key = $oldKey or $oldKey = ''">
                      <xsl:call-template name="filter"> 
                         <xsl:with-param name="oldKey" select="$key" />
                         <xsl:with-param name="items" select="$items"/> 
                         <xsl:with-param name="result" select="$result | $items[*[name() = $key and . = $value]]"/> 
                         <xsl:with-param name="filterKeys" select="substring-after($filterKeys, '~~')"/> 
                         <xsl:with-param name="filterValues" select="substring-after($filterValues, '~~')"/>                
                      </xsl:call-template> 
                   </xsl:when>
                   <xsl:otherwise>
                      <xsl:call-template name="filter"> 
                         <xsl:with-param name="oldKey" select="$key" />
                         <xsl:with-param name="items" select="$result[*[name() = $key and . = $value]]"/> 
                         <xsl:with-param name="result" select="$result[*[name() = $key and . = $value]]"/> 
                         <xsl:with-param name="filterKeys" select="substring-after($filterKeys, '~~')"/> 
                         <xsl:with-param name="filterValues" select="substring-after($filterValues, '~~')"/>                
                      </xsl:call-template> 
                   </xsl:otherwise>
             </xsl:when> 
             <xsl:otherwise> 
                <xsl:for-each select="$result"> 
                   <xsl:copy-of select="."/> 
                </xsl:for-each> 
             </xsl:otherwise> 
          </xsl:choose> 
       </xsl:template> 
     
    </xsl:stylesheet>
    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?> 
    <test> 
       <personne> 
          <nom>SMITH</nom> 
          <prenom>John</prenom> 
          <pays>US</pays> 
       </personne> 
       <personne> 
          <nom>DOUGLAS</nom> 
          <prenom>Jean</prenom> 
          <pays>US</pays> 
       </personne> 
    </test>
    Ce que je n'aime pas, c'est d'être obligé de répèter certaines déclaration de paramètre mais je ne peux pas mettre un choose dans <xsl:call-template>

    Encore une fois, merci énormément pour ton aide!!!!

    -Capt!
    - Capt.

    Proverbe Shadok:
    S'il n'y a pas de solutions, il n'y a pas de problèmes

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XSLT] Tri dynamique
    Par gregb34 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 06/02/2006, 12h52
  2. [JSTL] Test dynamique par rapport à un paramètre
    Par cosmos38240 dans le forum Taglibs
    Réponses: 3
    Dernier message: 21/12/2005, 20h05
  3. [XSLT] Test xsl:if
    Par virgul dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 19/12/2005, 10h05
  4. [XSLT] Test égalité noeuds différents
    Par bruno782 dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 24/10/2005, 20h58
  5. xslt --> test sur les chiffres
    Par yos dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 05/09/2005, 13h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo