Précédent   Forum des professionnels en informatique > Autres langages > XML/XSL et SOAP
XML/XSL et SOAP Forum d'entraide sur XML et SOAP. Avant de poster -> FAQ XML, Sources XML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/01/2012, 07h56   #1
Invité régulier
 
Inscription : janvier 2007
Messages : 27
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 27
Points : 7
Points : 7
Par défaut position d'élément selon critère

Bonjour
je cherche une expression XPath qui permet de retourner la position d'un élément dans un NodeSet avec un critère. par exemple dans le code suivant, je cherche la position de l'élément "personne" ayant @id="p23":
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
<personnes>
    <personne id="p1">
            <!-- des sous éléments-->
    </personne>
    <personne id="p23">
            <!-- des sous éléments-->      
    </personne>
    <personne id="p34">
            <!-- des sous éléments-->
    </personne>
</personnes>
Merci d'avance
yassou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 09h05   #2
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 456
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 456
Points : 2 159
Points : 2 159
Essaye ça : /personnes/personne[@id='p23']/position().

Ca te donnera la position de l'élément "personne" relativement à son élément parent "personnes".
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 10h58   #3
Invité régulier
 
Inscription : janvier 2007
Messages : 27
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 27
Points : 7
Points : 7
Merci pour la réponse, mais l'expression XPath
Code :
/personnes/personne[@id='p23']/position()
ne marche pas. J'utilise Exchanger XML Editor V3.3.01.
En fait, la dernière étape de l'expression (/position()) ne respecte pas la syntaxe XPath: Axe::test [predicat]. De plus la fonction position() doit figurer dans la partie prédicat, parce qu’elle n'a pas d'argument.
yassou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 11h37   #4
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 456
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 456
Points : 2 159
Points : 2 159
Alors essaye ça : position(/personnes/personne[@id='p23']) ou ça : count(/personnes/personne[@id='p23']/preceding-sibling::personne)+1.
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/01/2012, 11h40   #5
Expert Confirmé Sénior
 
Inscription : septembre 2004
Messages : 5 092
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 092
Points : 7 019
Points : 7 019
À ma connaissance en XPath ce n'est pas possible.

Et en fait en XSLT je ne sais pas vraiment comment faire ça.

Voici certaines approches :

Code :
1
2
3
4
5
6
<xsl:for-each select="personne">
  <xsl:variable name="position" select="position()"/>
  <xsl:if test="@id='p23'">
    <!-- traiter le nœud. La position peut être obtenue avec position() ou $position -->
  </xsl:if>
</xsl:for-each>
Ou

Code :
1
2
3
<xsl:template match="/personnes/personne[@id='p23']">
  <!-- traiter le nœud. La position peut être obtenue avec position() -->
</xsl:template>
thelvin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 15h28   #6
Invité régulier
 
Inscription : janvier 2007
Messages : 27
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 27
Points : 7
Points : 7
Je te remercies Loceka l'expression : count(/personnes/personne[@id='p23']/preceding-sibling::personne)+1. marche très bien.
Est ce qu'on peut généraliser cette solution? là je ne sais pas.
yassou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 16h40   #7
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 456
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 456
Points : 2 159
Points : 2 159
Qu'est-ce que tu entends par "généraliser" ?
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 17h49   #8
Membre confirmé
 
Inscription : octobre 2011
Messages : 188
Détails du profil
Informations forums :
Inscription : octobre 2011
Messages : 188
Points : 287
Points : 287
Citation:
Est ce qu'on peut généraliser cette solution?
Il faut entendre ça: qui parle une position parle en référence d'un ensemble ordonné de noeuds et l'order est plus souvent que non l'ordre documentaire.

Supposons un document plus élaboré tout en gardant id qui soit unique (ce n'est nécessaire mais ça simplifie le discours) pour illustration:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
<personnes>
    <any></any>
    <personne id="p1">
        <!-- des sous éléments-->
        <personne id="pp1">pp1</personne>
        <personne id="pp2">pp2</personne>
        <any>
            <personne id="ppp1">ppp1</personne>
        </any>
    </personne>
    <any></any>
    <personne id="p23">
        <!-- des sous éléments-->      
    </personne>
    <personne id="p34">
        <!-- des sous éléments-->
    </personne>
    <any />
</personnes>
Alors dans les cas les plus caractéristiques:
[1]
[1.1] ensemble ordonné: (//personne)
[1.2] localisation du noeud: (//personne)[@id='p23']
[1.3] position index: 5
[1.4] xpath: count((//personne)[@id='p23']/preceding::personne)+1

[2]
[2.1] ensemble ordonné: (//*)
[2.2] localisation du noeud: (//*)[@id='p23']
[2.3] position index: 8
[2.4] xpath: count((//*)[@id='p23']/preceding::*)+1

[3]
[3.1] ensemble ordonné: (/personnes/personne)
[3.2] localisation du noeud: (/personnes/personne)[@id='p23']
[3.3] position index: 2
[3.4] xpath: count((/personnes/personne)[@id='p23']/preceding-sibling::personne)+1

[4]
[4.1] ensemble ordonné: (/personnes/*)
[4.2] localisation du noeud: (/personnes/*)[@id='p23']
[4.3] position index: 4
[4.4] xpath: count((/personnes/*)[@id='p23']/preceding-sibling::*)+1

Voici un xslt pour illustrer ça.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
    <root>
       <xsl:call-template name="get_pos" />
    </root>
</xsl:template>
<xsl:template name="get_pos">
    <descendant_axis>
        <xsl:value-of select="count((//personne)[@id='p23']/preceding::personne)+1" />
    </descendant_axis>
    <descendant_axis>
        <xsl:value-of select="count((//*)[@id='p23']/preceding::*)+1" />
    </descendant_axis>
    <child_axis>
        <xsl:value-of select="count(personnes/personne[@id='p23']/preceding-sibling::personne)+1" />
    </child_axis>
    <child_axis>
        <xsl:value-of select="count(personnes/*[@id='p23']/preceding-sibling::*)+1" />
    </child_axis>
</xsl:template>
Voilà en gros c'est ça.
tsuji est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 22h25   #9
Expert Confirmé Sénior
 
Inscription : septembre 2004
Messages : 5 092
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 092
Points : 7 019
Points : 7 019
Bien vu, merci pour le truc de l'équivalence count() <=> position.
thelvin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 22h59   #10
Invité régulier
 
Inscription : janvier 2007
Messages : 27
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 27
Points : 7
Points : 7
ce qu'il faut retenir, selon le contexte de la position recherché, (position parmi tous les éléments ou parmi un ensembles des mêmes élément) on doit compter le nombre des éléments précédents ou nombre des frères précédents.
yassou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 23h42   #11
Expert Confirmé Sénior
 
Inscription : septembre 2004
Messages : 5 092
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 092
Points : 7 019
Points : 7 019
Ce qu'il faut retenir, c'est qu'il faut compter le bon nombre de choses en fonction de ce qu'on cherchait à obtenir.
thelvin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2012, 08h26   #12
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 456
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 456
Points : 2 159
Points : 2 159
Citation:
Envoyé par yassou Voir le message
ce qu'il faut retenir, selon le contexte de la position recherché, (position parmi tous les éléments ou parmi un ensembles des mêmes élément) on doit compter le nombre des éléments précédents ou nombre des frères précédents.
Ce seront toujours des frères (preceding-sibling) mais dans certains cas on compte seulement les éléments qui ont le même nom (dans ce cas, tous les éléments personne), dans d'autres cas on compte tous les frères.
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2012, 10h59   #13
Invité régulier
 
Inscription : janvier 2007
Messages : 27
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 27
Points : 7
Points : 7
Merci pour les précisions, thelvin à mieux exprimer ce que je voulais dire, tous dépend des cas.
yassou est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h28.


 
 
 
 
Partenaires

Hébergement Web