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 :

Pourquoi une requête fonctionne, et pas l'autre ? [XPATH 2.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre à l'essai
    Homme Profil pro
    Cosmonaute
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Cosmonaute

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Points : 22
    Points
    22
    Par défaut Pourquoi une requête fonctionne, et pas l'autre ?
    Bonjour,

    je viens d'apprendre comment écrire une requête XPATH. J'ai un petit document XML, le but de la requête est celui-ci:
    Sélectionner le deuxième nœud "personne" dont le pays de domiciliation est la France .
    (je mets le document XML en premier puis vient la question…)
    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
    57
    58
    <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <repertoire>
      <!-- John DOE -->
      <personne sexe="masculin">
        <nom>DOE</nom>
        <prenom>John</prenom>
        <adresse>
          <numero>7</numero>
          <voie type="impasse">impasse du chemin</voie>
          <codePostal>75015</codePostal>
          <ville>PARIS</ville>
          <pays>FRANCE</pays>
        </adresse>
        <telephones>
          <telephone type="fixe">01 02 03 04 05</telephone>
          <telephone type="portable">06 07 08 09 10</telephone>
        </telephones>
        <emails>
          <email type="personnel">john.doe@wanadoo.fr</email>
          <email type="professionnel">john.doe@societe.com</email>
        </emails>
      </personne>
     
      <!-- Marie POPPINS -->
      <personne sexe="feminin">
        <nom>POPPINS</nom>
        <prenom>Marie</prenom>
        <adresse>
          <numero>28</numero>
          <voie type="avenue">avenue de la république</voie>
          <codePostal>13005</codePostal>
          <ville>MARSEILLE</ville>
          <pays>FRANCE</pays>
        </adresse>
        <telephones>
          <telephone type="professionnel">04 05 06 07 08</telephone>
        </telephones>
        <emails>
          <email type="professionnel">contact@poppins.fr</email>
        </emails>
      </personne>
     
    	<!-- Batte MAN -->
      <personne sexe="masculin">
        <nom>MAN</nom>
        <prenom>Batte</prenom>
        <adresse>
          <numero>24</numero>
          <voie type="avenue">impasse des héros</voie>
          <codePostal>11004</codePostal>
          <ville>GOTHAM CITY</ville>
          <pays>USA</pays>
        </adresse>
        <telephones>
          <telephone type="professionnel">01 03 05 07 09</telephone>
        </telephones>
      </personne>
    </repertoire>
    J'ai trouvé un requête qui fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne[adresse/pays='FRANCE'][position()=2]
    J'en ai essayé une autre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne/adresse[pays='FRANCE']/parent::personne[position()=2]
    Pourquoi cette deuxième requête ne fonctionne-t-elle pas ?

    Avec un autre exercice, dont le but était:
    Sélectionner le nœud "personne" correspondant à l'individu ayant au moins 2 numéros de téléphone.
    J'avais fait comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /child::repertoire/child::personne/child::telephones[count(telephone)>=2]/parent::personne
    Ça avait l'air de marcher, le résultat était celui attendu, mais je ne suis pas certain que ce soit juste…


    Merci à vous.

  2. #2
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Le predicat postion()='2' s'applique à l'ensemble de noeuds duquel il attache. Comme il n'y a qu'un parent ou sans pour chaque noeud de par la définition d'un arbre, le xpath ne trouve rien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne/adresse[pays='FRANCE']/parent::personne[position()=2]
    On peut faire un regroupement par parenthèes, comme ça et bien d'autres variants.
    Code xpath : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (/repertoire/personne/adresse[pays='FRANCE']/parent::personne)[position()=2]
    ou
    (/repertoire/personne/adresse[pays='FRANCE'])[position()=2]/parent::personne
    On peut faire economie de l'écriture avec [position()='2'] et simplement écrire comme [2] évidemment.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Cosmonaute
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Cosmonaute

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Points : 22
    Points
    22
    Par défaut
    Merci pour ces informations précieuses

    J'ai mis du temps !

    La requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne/adresse[pays='FRANCE']
    donne comme 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
    Element='<adresse>
          <numero>7</numero>
          <voie type="impasse">impasse du chemin</voie>
          <codePostal>75015</codePostal>
          <ville>PARIS</ville>
          <pays>FRANCE</pays>
        </adresse>'
    Element='<adresse>
          <numero>28</numero>
          <voie type="avenue">avenue de la république</voie>
          <codePostal>13005</codePostal>
          <ville>MARSEILLE</ville>
          <pays>FRANCE</pays>
        </adresse>'

    Rem
    : le résultat est scindé en deux branches i.e. deux éléments <address>…</address> et <address>…</address>

    Vient ensuite une autre étape:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parent::personne[position()=2]
    Celle-ci s'applique séparément à chacune de ces deux branches.
    Cette étape:
    1. axe ainsi vers l'élément parent (qui est unique !!) du premier élément `address`, et sélectionne le numéro [2]. Or il n' y a qu'un seul parent, donc le résultat est vide.
    2. axe ainsi vers l'élément parent (qui est unique !!) du second élément `address`, et sélectionne le numéro [2]. Or il n' y a qu'un seul parent, donc le résultat est vide.


    Pour vulgariser, c'est un peu comme si la dernière étape avait agit deux fois.

    =======================================================================

    Avec les parenthèses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (/repertoire/personne/adresse[pays='FRANCE']/parent::personne)[position()=2]
    L'étape "agit" globalement (conjointement) sur les deux éléments `address`, trouve deux parents et ainsi, avec le prédicat `position()=2`, sélectionne le deuxième.
    Cette fois-ci le résultat est non vide.
    CQFD

    Pour vulgariser, ici c'est un peu comme si la dernière étape avait agit une seule fois sur l'ensemble résultant de l'étape précédente…

    Je mets en résolu.

    =======================================================================

    PS:
    même principe pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (/repertoire/personne/adresse[pays='FRANCE'])[position()=2]/parent::personne

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Oui enfin remonter au parent c'est quand même assez rarement intelligent.

    Les requêtes peuvent se faire simplement comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne[adresse/pays='FRANCE'][2]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /repertoire/personne[count(telephones/telephone) >= 2]
    Quel intérêt de compliquer à ce point ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre à l'essai
    Homme Profil pro
    Cosmonaute
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Cosmonaute

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Points : 22
    Points
    22
    Par défaut
    Oui, dans la vraie vie, pour un cas dont la résolution est nécessaire dans le cadre d'un projet, c'est juste. Ce n'est pour le moment pas mon cas: je n'ai aucune expérience et j'apprends seul. Aussi j'ai eu certaines difficultés à bien comprendre ces requêtes de base. Sans compter certaines informations fausses que j'ai pu lire ci-et-là. Pour toutes ces raisons, j'ai trituré ce que j'avais sous la main, d'une manière pas toujours académique c'est probablement vrai !
    Finalement, je me suis retrouvé avec deux requêtes, l'une fonctionnait, très bien, l'autre tordue, improbable, inenvisageable pour quelqu'un avec une certaine expérience, non. Je me devais de comprendre pourquoi. Voilà !
    Merci encore, sans ton aide, ça aurait pris plus de temps c'est sûr.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/03/2018, 17h24
  2. Toutes les valeurs d'une requête ne sont pas traitées
    Par Lunaden dans le forum Requêtes
    Réponses: 2
    Dernier message: 02/06/2008, 16h03
  3. [SQL] Vérifier si une requête ne contient pas d'erreurs
    Par Sytchev3 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 19/10/2007, 16h36
  4. [MySQL] Une requête fonctionne et l'autre pas vraiment...
    Par gazouza dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 21/03/2006, 10h49
  5. [MySQL] Une requête n'aboutissant pas
    Par Livingstone dans le forum Langage SQL
    Réponses: 6
    Dernier message: 13/02/2006, 10h36

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