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] rechercher un noeud depuis le noeud courant


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut [XSLT] rechercher un noeud depuis le noeud courant
    J'ai un noeud courant du genre <node id="123">
    J'aimerais rechercher un autre noeud du genre <othernode term="123"> qui possède un fils <subnode>.
    Je pensais à un code de ce genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <xsl:template match="node">
    <xsl:value-of select="//othernode[@term={@id}]/subnode"/>
    </xsl:template>
    mais ça n'a pas l'air de fonctionner.
    Merci

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

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

    {} ne doit pas être utilisé pour faire des substitutions dans une expression XPath, mais uniquement dans des attributs contenant une chaîne quelconque.

    Dans ton cas, il suffit d'utiliser la fonction current(), qui comme son nom l'indique renvoie le noeud courant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="node"> 
      <xsl:value-of select="//othernode[@term=current()/@id]/subnode"/> 
    </xsl:template>
    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 éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Merci!

    C'est ce qu'on appelle une réponse complète

    Ainsi, "." et "current()" sont parfois interchangeables, mais pas toujours.
    <xsl:value-of select="."/> et <xsl:value-of select="current()"/> sont équivalents.
    Mais <xsl:value-of select="@id[.='123']"/> et <xsl:value-of select="@id[current()='123']"/> sont différents (pouquoi?).

    Je pense que j'ai besoin d'un bon didactitiel "pour les nulls" qui vulgarise XPath.

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par camboui
    Mais <xsl:value-of select="@id[.='123']"/> et <xsl:value-of select="@id[current()='123']"/> sont différents (pouquoi?).
    Parce que . désigne le noeud en cours à cette étape de l'évaluation de l'expression XPath (en l'occurrence l'attribut id dans ton exemple), tandis que current() désigne le noeud courant dans le contexte duquel l'expression XPath est évaluée, en d'autres termes celui dont le template s'exécute. La syntaxe abrégée . présente dans une expression XPath à plusieurs endroits ne désignera pas toujours le même noeud, tandis que current() est invariant. Ce n'est donc pas du tout la même chose.
    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

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Et encore merci!

    Ça me fait d'ailleurs poser une nouvelle question (désolé ):
    comment "mémoriser" ou "changer" un contexte Xpath?
    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <xsl:template match="node">
    <xsl:choose>
     <xsl:when test="//othernode[@term=current()/@id]/subnode">
      <xsl:value-of select="//othernode[@term=current()/@id]/subnode"/>
      <xsl:if test="//othernode[@term=current()/@id]/subnode/child">
       (le fils est <xsl:value-of select="//othernode[@term=current()/@id]/subnode/child"/>)
      </xsl:if>
     </xsl:when>
     <xsl:otherwise><xsl:apply-templates/></xsl:otherwise>
    </xsl:choose>
    </xsl:template>
    Je pense dans ce cas qu'il serait intéressant de travailler dans le contexte //othernode[@term=current()/@id]/subnode, les performances seraient sans doute améliorées (ainsi que la lisibilité du code).

  6. #6
    Membre éclairé Avatar de luta
    Inscrit en
    Novembre 2003
    Messages
    1 038
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 038
    Par défaut
    il y a quelque temps je voyais tres souvent des bouts de code de Grand Father et Erwy qui jouaient allegrement avec un fonction appellé
    generate-id() qui je ne sais pas à partir de quoi (certainement la position ds le doc, le contenu...) génére un id unique d un noeud ds le doc xml...
    donc tu peux tout a fait déclarer une variable contenant le generate-id() d un noeud que tu réutilisera pour retrouver ton noeud dans le doc!

    ...même si au début je ne comprenais rien à cette utilisation presque abusive de cette fonction, j avoue aujourd hui qu elle est très très utile...

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Euh... j'suis un peu perdu, là...

    Si je comprends bien, tu suggères un truc du genre
    <xsl:variable name="var" value="generate-id()"/>
    Puis de retrouver l'élément par le Xpath
    //node[@id=$var]

    Ça me parait un peu lourd et c'est un peu ce que je souhaite éviter. Ou alors je ne comprends pas.

    J'imagine un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <xsl:template match="node"> 
    <xsl:context name="ctxt" xpath="//othernode[@term=current()/@id]"/>
    <xsl:choose> 
     <xsl:when test="$ctxt/subnode"> 
      <xsl:value-of select="$ctxt/subnode"/> 
      <xsl:if test="$ctxt/subnode/child"> 
       (le fils est <xsl:value-of select="$ctxt/subnode/child"/>) 
      </xsl:if> 
     </xsl:when> 
     <xsl:otherwise><xsl:apply-templates/></xsl:otherwise> 
    </xsl:choose> 
    </xsl:template>
    Bien sûr ce code est faux car <xsl:context> n'existe pas, mais vous comprenez ce que je veux dire, n'est-ce- pas

  8. #8
    Membre éclairé Avatar de luta
    Inscrit en
    Novembre 2003
    Messages
    1 038
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 038
    Par défaut
    ce que je veux dire c qu une fois que tu as évaluer l id, tu n as plus besoin de retaper tout le xpath
    qt aux enfants de ce noeud tu peux encore utiliser l id en plus de parent::, ascendant::....

  9. #9
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    S'il ne faut plus retaper le Xpath, alors c'est bon
    Tu peux mettre une exemple de code?
    Merci!

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    generate-id() ne te sera d'aucun secours ici, on emploie généralement cette fonction XPath pour comparer des noeuds entre eux ou gérer des références croisées.

    Si tu veux alléger ton code, il suffit de conserver le noeud sélectionné dans une variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <xsl:template match="node"> 
      <xsl:variable name="myNode" select="//othernode[@term=current()/@id]/subnode"/>
      <xsl:choose> 
       <xsl:when test="$myNode"> 
        <xsl:value-of select="$myNode"/> 
        <xsl:if test="$myNode/child"> 
       (le fils est <xsl:value-of select="$myNode/child"/>) 
        </xsl:if> 
       </xsl:when> 
       <xsl:otherwise><xsl:apply-templates/></xsl:otherwise> 
      </xsl:choose> 
    </xsl:template>
    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 éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Comme le dirais le castor dans La Belle et Le Clochard, ça marrrrrche!

    Je me pose cependant la question suivante: est-ce que la variable mémorise la chaine de caractères ou le xpath correspondant?
    Je suppose qu'elle ne mémorise que la chaine de caractères et donc le xpath est recalculé à chaque référence faite à la variable. D'un point de vue performance on ne gagne pour ainsi dire rien, mais le code est plus lisible.

    Merci!

  12. #12
    Expert confirmé
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par camboui
    Je me pose cependant la question suivante: est-ce que la variable mémorise la chaine de caractères ou le xpath correspondant?
    Je suppose qu'elle ne mémorise que la chaine de caractères et donc le xpath est recalculé à chaque référence faite à la variable. D'un point de vue performance on ne gagne pour ainsi dire rien, mais le code est plus lisible.
    Perdu.
    La variable ne contient ni l'expression XPath ni le contenu du (ou des) noeuds sélectionnés, mais mémorise la liste des noeuds (NodeList) sélectionnés par l'expression XPath dans l'attribut select de xsl:variable. Toutes les expressions du style '$myNode/child' opèrent des sélections des noeuds child en partant directement des noeuds subnode contenus dans $myNode, donc sans reparcourir l'arbre XML et les othernode, etc. D'où gain de temps et de performances.
    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

  13. #13
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Mais c'est magnifique ça! Tant mieux alors

    Mais si je veux que la variable contienne une chaine de caractères sans plus, comment faire?
    Comme ceci
    <xsl:variable name="myNode" select="'//othernode[@term=current()/@id]/subnode'"/>
    au lieu de
    <xsl:variable name="myNode" select="//othernode[@term=current()/@id]/subnode"/>
    ? (chaine encadrée entre apostrophes)

    Donc si je tape simplement
    <xsl:variable name="myNode" select="Bonjour madame"/> il va y avoir une erreur?

    Décidemment, Xpath, xslt et touti quanti et un vrai mélimélo pour moi

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

Discussions similaires

  1. [XSLT] Recherche de noeud
    Par Laughing Man dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 08/09/2009, 15h25
  2. [XSLT] recherche de noeud
    Par jimmeu dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 20/02/2008, 12h12
  3. Réponses: 4
    Dernier message: 25/05/2007, 08h35
  4. [XSLT] remplacer le contenu d'un noeud
    Par casgr1 dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 29/06/2006, 09h50
  5. [XSLT] Connaitre le chemin d'un noeud
    Par virgul dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 02/03/2006, 13h48

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