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 :

Compteur XSL...Portée des variables limitée


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Compteur XSL...Portée des variables limitée
    Bonjour à tous,

    Je pense que pas mal de gens se sont déjà penchés sur la chose mais n'ayant rien trouvé sur le forum à ce sujet, je fais donc appel à l'abondance de matière grise présente dans cette communauté

    Supposons que l'on ait :
    - en entrée :
    un fichier xml du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <in:Interchange>
    		<se:UNB />
    		<me:MESSAGE>
    			<se:UNH />
    			<se:BGM />
    			<se:DTM />
    			<se:DTM />
    		</me:MESSAGE>
    	</in:Interchange>
    - En sortie on voudrait obtenir :
    un fichier xml du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <in:Interchange>
    		<se:UNB numLigne="1" />
    		<me:MESSAGE>
    			<se:UNH numLigne="2" ></se:UNH >
    			<se:BGM numLigne="3" ></se:BGM >
    			<se:DTM numLigne="4" ></se:DTM >
    			<se:DTM numLigne="5" ></se:DTM >
    		</me:MESSAGE>
    	</in:Interchange>
    - Pour ce faire on utilise une feuille xslt de pré traitement :

    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 match="/">
    		<in:Interchange>
    			<se:UNB>
    			<xsl:attribute name="numLigne">
    				<xsl:call-template name="compteur" ></xsl:call-template>
    			</xsl:attribute>
    			</se:UNB>
    			<xsl:for-each select="/in:Interchange/me:MESSAGE">
    				<me:MESSAGE>
    					<se:UNH>
    					<xsl:attribute name="numLigne">
    						<xsl:call-template name="compteur" ></xsl:call-template>
    					</xsl:attribute>
     
    					</se:UNH>
    					<se:BGM>
    					<xsl:attribute name="numLigne">
    						<xsl:call-template name="compteur" ></xsl:call-template>
    					</xsl:attribute>
    					</se:BGM>
    					<xsl:for-each select="se:DTM">
    						<se:DTM>
    						<xsl:attribute name="numLigne">
    							<xsl:call-template name="compteur" ></xsl:call-template>
    						</xsl:attribute>
    						</se:DTM>
    					</xsl:for-each>
    				</me:MESSAGE>
    			</xsl:for-each>
    		</in:Interchange>
    	</xsl:template>

    Est-il possible d'écrire un template "compteur" permettant de retourner un paramètre i et de l'incrémenter en i++ pour l'appel suivant ?

    Vos idées sont les bienvenues, par avance merci

  2. #2
    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 usi pas ur d'en voir l'intérêt ici

    Avec le bon Xpath et position() cela devrait suffire dans ton exemple

  3. #3
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    La numérotation ne devant se faire que sur les balises appartenant à l'espace de noms "se", est-il possible que la fonction position() ne tienne pas compte des balises appartenant aux autres espaces de noms ??

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 284
    Points : 349
    Points
    349
    Par défaut
    Ca dépend du XPath que tu utilises dans ton for-each.
    Dans ton exemple, ca devrait etre bon...
    Nicolas

  5. #5
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    bonjour,

    <xsl:template match = "/" >
    <xsl:apply-templates select = "//child::*" mode = "print" />
    </xsl:template>

    <xsl:template match = "*" mode = "print" >
    <xsl:copy>
    <xsl:attribute name="numLigne">
    <xsl:value-of select = "position()" />
    </xsl:attribute>
    </xsl:copy>
    </xsl:template>

    devrait donner le resultat attentue.

  6. #6
    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 lebarongeorges
    bonjour,

    <xsl:template match = "/" >
    <xsl:apply-templates select = "//child::*" mode = "print" />
    </xsl:template>

    <xsl:template match = "*" mode = "print" >
    <xsl:copy>
    <xsl:attribute name="numLigne">
    <xsl:value-of select = "position()" />
    </xsl:attribute>
    </xsl:copy>
    </xsl:template>

    devrait donner le resultat attentue.
    C'est bien vu, mais ce n'est pas tout à fait exact.
    Car seuls les éléments sans éléments enfants prennent un attribut numLigne, et on n'obtient pas une imbrication correcte des balises (il ne faut pas oublier d'appeler récursivement le template pour les éléments enfants) :

    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
    <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:template match = "/" > 
    		<xsl:apply-templates select = "*" mode = "print"/>
    	</xsl:template> 
     
    	<xsl:template match = "*" mode = "print" >
    	    <xsl:copy>
    		<xsl:if test="not(*)">
    			<xsl:attribute name="numLigne"> 
    			    <xsl:value-of select = "count(preceding::*[not(*)]) + 1" /> 
    			</xsl:attribute>
    		</xsl:if>
    		<xsl:apply-templates select="*" mode="print"/>
    		</xsl:copy>
    	</xsl:template>
     
    </xsl:stylesheet>
    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

  7. #7
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    bien vu, par contre si on voulait ecrire l'attribut numLigne uniquement sur les balises qui ont le namespace se, on fera comment ?

  8. #8
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    lanfeustdetroy, je ne vois pas l'interet de numeroter les balises...quel est le but de cette opération ?

  9. #9
    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 lebarongeorges
    bien vu, par contre si on voulait ecrire l'attribut numLigne uniquement sur les balises qui ont le namespace se, on fera comment ?
    Admettons que l'on ait le XML suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8"?>
    <in:Interchange xmlns:in="toto" xmlns:se="titi" xmlns:de="tata" xmlns:me="tutu"> 
          <se:UNB /> 
          <me:MESSAGE> 
             <se:UNH /> 
             <de:BGM /> 
             <se:DTM /> 
             <de:DTM /> 
          </me:MESSAGE> 
       </in:Interchange>
    Pour ne numéroter que les éléments appartenant à l'espace de noms 'titi', préfixés par se, il suffit de faire :
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:in="toto" xmlns:se="titi" xmlns:de="tata">
     
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     
    	<xsl:template match = "/" > 
    		<xsl:apply-templates select = "*" mode = "print"/>
    	</xsl:template> 
     
    	<xsl:template match = "*" mode = "print" >
    	    <xsl:copy>
    		<xsl:if test="not(*) and namespace-uri() = 'titi'">
    			<xsl:attribute name="numLigne"> 
    			    <xsl:value-of select = "count(preceding::se:*[not(*)]) + 1" /> 
    			</xsl:attribute>
    		</xsl:if>
    		<xsl:apply-templates select="*" mode="print"/>
    		</xsl:copy>
    	</xsl:template>
     
    </xsl:stylesheet>
    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

  10. #10
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par lebarongeorges
    lanfeustdetroy, je ne vois pas l'interet de numeroter les balises...quel est le but de cette opération ?
    Mon fichier en entrée est un fichier edi, après transcription en xml, chaque ligne de ce fichier représente un segment (balise appartenant au namespace se) et donc l'attribut numLigne représente le numéro de la ligne dans le fichier d'entrée, pour utilisation ultérieure (correction ou autre...)

    Après analyse de tout ça, la conclusion est la suivante :
    afin de ne numéroter que les balises appartenant à "se", le code est le suivant :
    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
    <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:template match = "/" > 
          <xsl:apply-templates select = "*" mode = "print"/>
       </xsl:template> 
     
       <xsl:template match = "*" mode = "print" > 
          <xsl:copy>
          <xsl:if test="substring(name(.), 1, 3)='se:'"> 
             <xsl:attribute name="numLigne"> 
                 <xsl:value-of select = "count(preceding::*[substring(name(.), 1, 3)='se:']) + count(ancestor::*[substring(name(.), 1, 3)='se:']) + 1" /> 
             </xsl:attribute> 
          </xsl:if> 
          <xsl:apply-templates select="*" mode="print"/> 
          </xsl:copy> 
       </xsl:template> 
     
    </xsl:stylesheet>
    Le problème est résolu

    Merci a GrandFather et lebarongeorges pour m'avoir mâché tout le boulot (pour ne pas dire que vous avez tout fait ^^)

  11. #11
    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
    Ton code serait plus robuste si tu déclarais les espaces de nom dans ton XSLT, et que tu utilisais namespace-uri() : le préfixe pourrait changer (passer de 'se' à 'me', par exemple) sans que tu aies quoi que ce soit à modifier dans ton code.
    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

  12. #12
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Voui très bonne idée, je vais faire comme dans ton exemple précédent

    Voici la version finale :
    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"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    							  xmlns:se="titi" >
     
       <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
     
       <xsl:template match = "*" >
          <xsl:copy> 
          <xsl:if test="namespace-uri() = 'titi'">
             <xsl:attribute name="numLigne"> 
                 <xsl:value-of select = "count(preceding::*[namespace-uri() = 'titi']) + count(ancestor::*[namespace-uri() = 'titi']) + 1" />
             </xsl:attribute> 
          </xsl:if> 
          <xsl:apply-templates /> 
          </xsl:copy> 
       </xsl:template> 
     
    </xsl:stylesheet>
    La feuille étant appelée dans un traitement intermédiaire, elle ne gère rien d'autre (un seul template). Les données entre balises du fichier source sont maintenant retranscrites dans le XML de sortie et les namespace sont désormais déclarés au sein de la feuille XSL.

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

Discussions similaires

  1. limiter la porte des variables
    Par ol9245 dans le forum MATLAB
    Réponses: 15
    Dernier message: 16/10/2009, 20h19
  2. Réponses: 8
    Dernier message: 17/02/2005, 09h05
  3. Portée des variables vbscript vers ASP
    Par Immobilis dans le forum ASP
    Réponses: 3
    Dernier message: 03/11/2004, 10h14
  4. [XSL]Problème de portée des variables
    Par djulesp dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/09/2004, 10h34
  5. [Portée] portée des variables
    Par parksto dans le forum Langage
    Réponses: 7
    Dernier message: 09/05/2004, 21h05

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