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] récupération de la position d´un parent


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 61
    Points : 51
    Points
    51
    Par défaut [XSLT] récupération de la position d´un parent
    Salut à tous,

    c´est encore moi avec un nouveau problème: J´aimerais savoir comment récupérer la position (avec la fonction position() ou autrement) d´un noeud enfant du noeud courant, sachant que ce noeud enfant a lui aussi été un noeud courant. Je m´explique par cette exemple de classification. Soit le fichier XML suivant:

    <?xml version="1.0"?>
    <Root>
    <!-- Definition de la classe Root et de ses sous élements qui sont aussi des classes-->
    <Classe code="A88"><nom>Classe Root</nom>
    <SousClasse code="A88.0"/>
    <SousClasse code="A88.1"/>
    </Classe>

    <!--Définition des sous-classes-->
    <Classe code="A88.0"><nom>Classe AB</nom>
    <SuperClasse code="A88"/>
    <SousClasse code="A88.01"/>
    </Classe>

    <Classe code="A88.1"><nom>Classe AC</nom>
    <SuperClasse code="A88"/>
    <SousClasse code="A88.11"/>
    </Classe>
    </Root>

    Cette Classification n´est qu´un extrait. Le doc contient la définition de bien d´autres classes qui ont des super classes ou des sous-classes (représentez-vous un arbre monohierarchique).

    Supposons qu´avec du XSLT, j´ai un template où je me trouve au noeud courant Root/Classe. J´aimerais pour chaque classe récupérer sa position ainsi que la position dans l´arbre (ou de la structure xml) de sa SuperClasse. J´aimerais donc avec une sortie telle:
    A88; position 1;
    A88.0; position 2; position 1
    A88.1; position 3; position 1
    (code de la classe; position courante de la classe; position courante de la Super-Classe)

    Pouvez-vous m´aider à réaliser cela avec xslt? Jusqu´ici avec la fonction position() je ne n´arrive qu´à avoir (code de la classe; position courante de la classe) mais pas la position courante de la Super-Classe du noeud courant. J´ai essayé en utilisant <xsl:variable/> pour mon incrémentation, mais je ne peux pas du tout changer la valeur de cette variable, une fois définie, elle reste constante.

    Toute aide serait plus que bienvenue. Merci.

    Sylvie

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Aucun moyen direct.

    Mais tu peux faire une boucle sur tous les éléments <Classe>, vérifier s'il répond à tes critères, et si oui, exploiter la valeur de position().

    Autre possibilité : adapter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    count(Classe[@code=current()/SuperClasse/@code]/preceding-sibling:Classe)

  3. #3
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 61
    Points : 51
    Points
    51
    Par défaut
    Merci Thelvin pour ta réponse. J´ai essayé ton code avec la fonction count(...) mais je n´obtiens que la valeur 1, vu que chaque classe n´a qu´une unique Superclasse. J´aimerais plutôt avoir la position de cette superclasse dans la structure de mon fichier XML.

    Maintenant, j´essaie ta première solution, mais Pourrais-tu me dire comment accéder à une classe-soeur lorsqu´on se trouve déjà dans une autre classe-soeur. Je m´explique: si j´ai ceci
    <root>
    <Classe A>...</Classe A>
    <Classe B>...</Classe B>
    </root>

    <xsl:template match="Classe B">
    <!-- conditions, operations -->
    </xsl:template>

    comment est ce qu´au sein de ce match, puis-je faire un autre match pour remonter à Classe A qui est une soeur (preceding-sibling) de Classe B, afin de prendre une information de Classe A dont j´ai besoin pour mieux définir Classe B?

    Merci pour toute aide.

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Hello,
    Au sein de ton template tu peux très bien faire ce genre d'XPATH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling:Classe[1]/nom/text()"/>
    Voir ajouter des prédicats pour affiner ta sélection des noeuds frères précédents.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="preceding-sibling:Classe[prédicat][1]/nom/text()"/>

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Citation Envoyé par sylvie Voir le message
    Merci Thelvin pour ta réponse. J´ai essayé ton code avec la fonction count(...) mais je n´obtiens que la valeur 1, vu que chaque classe n´a qu´une unique Superclasse. J´aimerais plutôt avoir la position de cette superclasse dans la structure de mon fichier XML.
    Ben ?

    Document :

    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
    <root>
      <Classe code="superA">
        <SousClasse code="C"/>
        <SousClasse code="D"/>
        <SousClasse code="E"/>
      </Classe>
      <Classe code="superB">
        <SousClasse code="F"/>
        <SousClasse code="G"/>
      </Classe>
      <Classe code="C">
        <SuperClasse code="superA"/>
      </Classe>
      <Classe code="D">
        <SuperClasse code="superA"/>
      </Classe>
      <Classe code="E">
        <SuperClasse code="superA"/>
      </Classe>
      <Classe code="F">
        <SuperClasse code="superB"/>
      </Classe>
      <Classe code="G">
        <SuperClasse code="superB"/>
      </Classe>
    </root>
    Transformation :

    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
    <xs:stylesheet version="1.0" xmlns:xs="http://www.w3.org/1999/XSL/Transform">
     
      <xs:template match="/">
      	<root>
      		<xs:apply-templates/>
      	</root>
      </xs:template>
     
      <xs:template match="Classe">
      <desc>
      	<xs:text>Classe </xs:text><xs:value-of select="@code"/>
        <xs:choose>
          <xs:when test="SuperClasse">
            superclasse : <xs:value-of select="SuperClasse/@code"/> ;
            position : <xs:value-of select="count(/root/Classe[@code=current()/SuperClasse/@code]/preceding-sibling::Classe)+1"/>
          </xs:when>
          <xs:otherwise>
          Pas de superclasse</xs:otherwise>
        </xs:choose>
      </desc>
      </xs:template>
     
    </xs: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
    19
    20
    21
    22
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <desc>Classe superA
          Pas de superclasse</desc>
      <desc>Classe superB
          Pas de superclasse</desc>
      <desc>Classe C
            superclasse : superA ;
            position : 1</desc>
      <desc>Classe D
            superclasse : superA ;
            position : 1</desc>
      <desc>Classe E
            superclasse : superA ;
            position : 1</desc>
      <desc>Classe F
            superclasse : superB ;
            position : 2</desc>
      <desc>Classe G
            superclasse : superB ;
            position : 2</desc>
    </root>
    Où est le problème ?

    Citation Envoyé par sylvie Voir le message
    Maintenant, j´essaie ta première solution, mais Pourrais-tu me dire comment accéder à une classe-soeur lorsqu´on se trouve déjà dans une autre classe-soeur. Je m´explique: si j´ai ceci
    <root>
    <Classe A>...</Classe A>
    <Classe B>...</Classe B>
    </root>

    <xsl:template match="Classe B">
    <!-- conditions, operations -->
    </xsl:template>

    comment est ce qu´au sein de ce match, puis-je faire un autre match pour remonter à Classe A qui est une soeur (preceding-sibling) de Classe B, afin de prendre une information de Classe A dont j´ai besoin pour mieux définir Classe B?

    Merci pour toute aide.
    Ce ne sont pas les solutions qui manquent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xs:for-each select="preceding-sibling::Classe">
    <!-- faire quelque chose avec la classe sœur --> 
    </xs:for-each>

  6. #6
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 61
    Points : 51
    Points
    51
    Par défaut
    Merci beaucoup à Morbo et à Thelvin pour leurs précieuses aides. J´ai enfin pu résoudre mon problème. J´avais en effet tout d´abord essayé ceci (voir suggestion de Morbo):
    <xsl:value-of select="preceding-sibling::Classe[@code=$superclass1]/@code"/>
    avec:
    <xsl:variable name="superclass1"><xsl:value-of select="current()/SuperClasse/@code" /></xsl:variable>
    Mais cela me donnait tout juste le code de la superclasse correspondante et pas sa position (néanmoins c´était déjà un pas en avant).

    Puis Thelvin, ton dernier exemple a été la clé, j´avais mal ajusté ton premier exemple. Mais néanmoins, j´ai du pour le test changer de prédicat afin d´a voir ceci qui a très bien marché pour mon cas:
    <xsl:choose>
    <xsl:when test="SuperClasse/@code=preceding-sibling::Classe/@code">
    <xsl:value-of select="count(/root/Classe[@code=current()/SuperClasse/@code]/preceding-sibling::Classe)+1"/>
    </xsl:when>
    <xsl:otherwise><xsl:value-of select="0"/></xsl:otherwise>
    </xsl:choose>

    En faisant des recherches, vu que j´étais obsédée d´utiliser la fonction position() du XSLT, j´ai trouvée cette solution qui marche aussi bien au sein d´un template:

    <xsl:variable name="superclass1"><xsl:value-of select="current()/SuperClasse/@code" /></xsl:variable>
    <xsl:for-each select="preceding-sibling::Classe">
    <xsl:if test="preceding-sibling::Classe/@code=$superclass1">
    <xsl:value-of select="position()-1"/>
    </xsl:if>
    </xsl:for-each>

    Merci encore à vous deux!

    Sylvie

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 09/09/2006, 23h49
  2. Récupération De la valeur d’un champ
    Par jeha dans le forum Access
    Réponses: 1
    Dernier message: 13/08/2006, 21h10
  3. [SQL] Récupération de la position d'un élément
    Par Kerod dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 16/05/2006, 02h55
  4. [XSLT] [PHP 5] fonction position()
    Par sharper dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 01/12/2005, 12h58
  5. [XSLT] Récupération du nom du fichier XML analysé
    Par Patkaza dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/01/2005, 11h28

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