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 :

Astuce pour récupérer une variable modifiée


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut Astuce pour récupérer une variable modifiée
    Bonjour,

    Suite à mon post sur la possibilité de modifier une variable par une astuce (je sais c'est impossible) je me permets de vous présenter donc une "astuce" qui remplit les conditions dont j'ai besoin et qui peut peut-être vous servir.

    Admettons que je passe une variable à un template et que je souhaite récupérer sa valeur modifiée. Dans ce cas, il suffit de faire quelquechose de ce style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <xsl:variable name="myVar">
    	<xsl:call-template name="myTemplate">
    		<xsl:with-param name="myParam"><xsl:value-of select="$myVar"/></xsl:with-param>
    	</xsl:call-template>
    </xsl:variable>
    et dans le template, de renvoyer la "nouvelle" valeur de la variable myVar. On se retrouve alors avec une nouvelle variable, mais qui porte le même nom, et avec la valeur modifiée.

    Par contre, lorsque dans le template, on souhaite aussi "sortir" des données dans le fichier de sortie, on se retrouve coincé, on ne peut plus remonter la nouvelle valeur de la variable.

    Maintenant, voilà "l'astuce" pour remonter les données de sortie pour le fichier ET la nouvelle valeur de la variable :

    Exemple de template
    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
     
    <xsl:template name="myTemplate">
    	<xsl:param name="myParam"/>
     
    	<!-- Retrieve 3 first char from param -->
    	<xsl:variable name="localVar">
    		<xsl:value-of select="substring($myParam, 1,3)"/>
    	</xsl:variable>
     
    	<!-- remove 3 first char from var to be returned -->
    	<xsl:variable name="returnedVar">
    		<xsl:value-of select="substring($myParam, 4)"/>
    	</xsl:variable>
     
    	<!-- Define XML output -->
    	<xsl:variable name="outputXML">
    		<myTag>
    			<xsl:value-of select="$localVar"/>
    		</myTag>
    	</xsl:variable>
     
    	<!-- Returns combination of new var value, and XML output -->
    	<output>
    		<returnedValue>
    			<xsl:value-of select="$returnedVar"/>
    		</returnedValue>
    		<outputXML>
    			<xsl:copy-of select="$outputXML"/>			
    		</outputXML>
    	</output>
    </xsl:template>
    L'appel de mon template permettant de récupérer la nouvelle valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <xsl:variable name="myVar">ABCDEFGHIJK</xsl:variable>
     
    <!-- set output data -->
    <xsl:variable name="tmp">
    	<xsl:call-template name="myTemplate">
    		<xsl:with-param name="myParam"><xsl:value-of select="$myVar"/></xsl:with-param>
    	</xsl:call-template>
    </xsl:variable>
     
    <!-- Separate new returned value from output XML -->
    <xsl:variable name="myVar"><xsl:value-of select="$tmp/output/returnedValue"/></xsl:variable>		
    <xsl:variable name="outputXML"><xsl:copy-of select="$tmp/output/outputXML/*"/></xsl:variable>
    Dans la variable myVar, après l'appel de mon template j'ai bien "CDEFGHIJK" et dans outputXML j'ai ce que je veux mettre dans mon fichier de sortie : <myTag>ABC</myTag>

    Qu'en pensez-vous?

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    génial ton astuce.
    Merci, ca marche trop bien

  3. #3
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    J'ai essayé d'utiliser ton astuce, mais elle ne marche pas.

    J'ai un fichier XML comme suit:
    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
    <csv>
    <lib>1</lib>
    <data>a</data>
    <data>b</data>
    <data>c</data>
    <data>d</data>
    <lib>2</lib>
    <data>e</data>
    <data>f</data>
    <data>g</data>
    <data>h</data>
    <lib>3</lib>
    <data>i</data>
    <data>j</data>
    <data>k</data>
    <data>l</data>
    </csv>
    la sortie attendue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1a;1b;1c;1d;
    2e;2f;2g;2h;
    3i;3j;3k;3l;
    du coup, j'ai construit la XSL suivante:
    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
    <?xml version="1.0" encoding="iso-8859-1"?>
    <xsl:stylesheet
    	version="1.0"
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
    	<xsl:output method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="no"/>
     
    	<xsl:template match="csv">
    		<xsl:variable name="LIB">
    			<xsl:call-template name="getLIB">
    				<xsl:with-param name="param"><xsl:value-of select="$LIB"/></xsl:with-param>
    			</xsl:call-template>
     
    			<xsl:apply-templates>
    				<xsl:with-param name="param"><xsl:value-of select="$LIB"/></xsl:with-param>
    			</xsl:apply-templates>
    		</xsl:variable>
    	</xsl:template>
     
    	<xsl:template name="getLIB" match="lib">
    		<xsl:variable name="param"><xsl:value-of select="current()"/></xsl:variable>
    	</xsl:template>
     
    	<xsl:template match="data">
    		<xsl:param name="param"/>
    		<xsl:value-of select="$param"/><xsl:value-of select="current()"/>;
    	</xsl:template>
     
     
    	<xsl:template match="text()"/>
     
    </xsl:stylesheet>
    Je ne vois pas mon erreur, peut etre que vous, habitué(e)s du langage, verrez rapidement ma connerie
    De plus, je n'ai toujours pas trouvé comment aller à la ligne, mais bon, ceci est une autre histoire...


    Cdlt,


    Billy

  4. #4
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Pour le retour a la ligne il faut faire ca il me semble :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:text>&#xA;</xsl:text>
    Pour votre code, vous utilisez en paramètre la variable $LIB alors qu'elle n'a pas encore de valeur (puisque sa valeur correspondra au retour du template) par contre je suis loin d'être assez familier du langage pour vous aider. Le mieux est de faire un nouveau post en expliquant votre problèmes quelqu'un pourra surement vous répondre.
    En regardant votre code vous donnez l'impression de tout stocker dans des variables du coup rien ne "ressort de vos templates".

    Bon courage!

  5. #5
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Merci pour la réponse (le coup du \n).

    Je n'ai pas trouvé de solutions à mon problème, je suis donc parti sur une autre voie.

  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 vois moyennement l'intérêt
    ce sont des variables locales qui portent le même nom (généralement quand un problème de cette nature ce pose , il y a "vis de conception", on doit pouvoir y arriver de façon plus propre) , si tu t'amuses à la faire sur les même niveaux tu vas avoir une surprise et tu abuses de certaines ecritures
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:with-param name="param"><xsl:value-of select="$LIB"/></xsl:with-param> 
    <xsl:variable name="param"><xsl:value-of select="current()"/></xsl:variable>
    ec...
    à remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <xsl:with-param name="param" select="$LIB"></xsl:with-param>
    <xsl:variable name="param" select="current()"></xsl:variable>
    le changment n'est pas anodin (surtout en xslt 1.0)

  7. #7
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    ah bon! merci pour l'info.

    Par contre, la structure du fichier XML m'est imposé, donc je dois faire avec...

    J'essaye en ce moment avec following-sibbling, mais ca marche pas

  8. #8
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Ca me saoule ce langage!!!! Je prefère largement Prolog!

    Qqun pour mayday?
    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
    <?xml version="1.0" encoding="iso-8859-1"?>
     
    <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
    <xsl:output method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="no"/>
     
    	<xsl:template match="csv">
    		<xsl:apply-templates/>	
    	</xsl:template>
     
    	<xsl:template match="lib">
    		<xsl:variable name="param" select="current()"/>
     
    		<xsl:variable name="positionRel" select="count(../lib/preceding-sibling::lib)"/>
    		<xsl:variable name="positionAbs" select="position()"/>
    		<xsl:variable name="position2Rel" select="$positionRel+1"/>
    		<xsl:variable name="position2Abs" select="count(../lib[$position2Rel]/preceding-sibling::*)+1"/>
     
    		<xsl:apply-templates mode="data" select="../data[position() &gt; $positionAbs+-1 and position() &lt; $position2Abs]">
    			<xsl:with-param name="param" select="$param"/>
    		</xsl:apply-templates>
    	</xsl:template>
     
    	<xsl:template match="data" mode="data">
    		<xsl:param name="param"/>
     
    		<xsl:value-of select="$param"/><xsl:value-of select="current()"/>;
    	</xsl:template>
     
    	<xsl:template match="text()"/>
    </xsl:stylesheet>
    Solution pour l'instant
    Merci de comprendre ma frustration.

  9. #9
    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
    Voir les codes sources ton problème se rapproche de celui-ci
    http://xml.developpez.com/sources/?p...bo#IV_position

  10. #10
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    J'ai une solution qui marche, mais je suis perplexe sur les performances. Dans mon exemple, cela serait parfait, mais imaginons un fichier xml très gros? j'ai peur de noyer les perfs, qu'en pensez-vous?

    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
    <?xml version="1.0" encoding="iso-8859-1"?>
    <xsl:stylesheet
    	version="1.0"
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
    	<xsl:output method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="no"/>
     
    	<xsl:template match="csv">
    		<xsl:apply-templates/>
    	</xsl:template>
     
    	<xsl:template match="data">
    		<!-- chercher le dernier libelle -->
    		<xsl:variable name="param" select="preceding-sibling::lib[1]"/>
     
    		<xsl:value-of select="$param"/><xsl:value-of select="current()"/>;
     
    	</xsl:template>
     
    	<xsl:template match="text()"/>
     
    </xsl:stylesheet>

    PS: Merci Erwy pour le lien, je l'avais déjà vu, mais je n'ai pas réussi à m'en servir...

  11. #11
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Bon, j'ai fait des tests:

    44sec pour 10 000 entrées

    On repart donc de zero... (enfin presque)

  12. #12
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut Yeepeee!!
    Bon, j'ai réussi à écourter la durée d'execution à 9secondes
    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
    <?xml version="1.0" encoding="iso-8859-1"?>
    <xsl:stylesheet
    	version="1.0"
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
    	<xsl:output method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="no"/>
     
     
    	<xsl:template match="csv">
    		<xsl:apply-templates/>
    	</xsl:template>
     
    	<xsl:template match="lib">
    		<xsl:variable name="LIB" select="current()"/>
    		<xsl:variable name="POS" select="position()"/>
    		<xsl:variable name="NEXTPOS" select="count(following-sibling::lib[1]/preceding-sibling::*)"/>
     
    		<xsl:choose>
    			<xsl:when test="$NEXTPOS &gt; 0">
    				<xsl:apply-templates mode="limit" select="../data[position() &gt; $POS+-1 and position() &lt; $NEXTPOS+1]">
    					<xsl:with-param name="param" select="$LIB"/>
    				</xsl:apply-templates>
    			</xsl:when>
    			<xsl:otherwise>
    				<!-- on poursuit pour tous les tr restants -->
    				<xsl:apply-templates mode="limit" select="../data[position() &gt; $POS+-1]">
    					<xsl:with-param name="param" select="$LIB"/>
    				</xsl:apply-templates>
    			</xsl:otherwise>
    		</xsl:choose>
    	</xsl:template>
     
    	<xsl:template match="data" mode="limit">
    		<xsl:param name="param"/>
     
    		<xsl:value-of select="$param"/><xsl:value-of select="current()"/>;<xsl:text>&#xA;</xsl:text>
    	</xsl:template>
     
    	<xsl:template match="text()"/>
     
    </xsl:stylesheet>

    Je savais que ce langage était magnifique!!!!


    Merci pour votre aide, et surtout ma patience


    Cordialement,



    Billy

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/01/2012, 21h51
  2. Réponses: 1
    Dernier message: 26/03/2009, 14h28
  3. [SQL2K5] Astuce pour utiliser une variable à valeur multiple
    Par Jinroh77 dans le forum Développement
    Réponses: 0
    Dernier message: 28/05/2008, 14h27
  4. Réponses: 17
    Dernier message: 01/06/2007, 08h16
  5. Réponses: 2
    Dernier message: 14/04/2006, 18h40

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