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]déplacement de noeuds


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 22
    Points : 18
    Points
    18
    Par défaut [XSLT]déplacement de noeuds
    Bonjour,

    Je débute dans XSLT j'aimerai transormer le document 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
    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
    <Services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<Service>
    		<DescriptionContract>
    			<Name>monservice_4op</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>GoogleSearchInterface</IName>
    			<OpName>doGoogleSearch</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract/>
    		<InterfaceContract>
    			<IName>2</IName>
    			<OpName>OtherOperation</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract/>
    		<InterfaceContract>
    			<IName>3</IName>
    			<OpName>Operation3</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract/>
    		<InterfaceContract>
    			<IName>4</IName>
    			<OpName>Operation4</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract>
    			<Name>CustomerVerification</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>ICustomer</IName>
    			<OpName>doValidateMemberShip</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract/>
    		<InterfaceContract>
    			<IName>2</IName>
    			<OpName>doMySecondOperation</OpName>
    		</InterfaceContract>
    	</Service>
    	<Service>
    		<DescriptionContract>
    			<Name>monservice_simple</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>TrySearchInterface</IName>
    			<OpName>doGoogleSearch</OpName>
    		</InterfaceContract>
    	</Service>
    </Services>

    en:


    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
    <Services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<Service>
    		<DescriptionContract>
    			<Name>monservice_4op</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>GoogleSearchInterface</IName>
                            <Operation Contract>
    			      <OpName>doGoogleSearch</OpName>
                            </Operation Contract>
                           <Operation Contract>
    			      <OpName>OtherOperation</OpName>
                            </Operation Contract>
                            <Operation Contract>
    			      <OpName>Operation3</OpName>
                            </Operation Contract>
                            <Operation Contract>
    			      <OpName>Operation4</OpName>
                            </Operation Contract>
    		</InterfaceContract>
    	</Service>
     
    	<Service>
    		<DescriptionContract>
    			<Name>CustomerVerification</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>ICustomer</IName>
                            <Operation Contract>
    			      <OpName>doValidateMemberShip</OpName>
                            </Operation Contract>
                            <Operation Contract>
    			      <OpName>doMySecondOperation</OpName>
                            </Operation Contract>
    		</InterfaceContract>
    	</Service>
     
    	<Service>
    		<DescriptionContract>
    			<Name>monservice_simple</Name>
    		</DescriptionContract>
    		<InterfaceContract>
    			<IName>TrySearchInterface</IName>
    			<OpName>doGoogleSearch</OpName>
    		</InterfaceContract>
    	</Service>
    </Services>


    C'est à dire:

    1°) Seul les noeuds qui ont Service/DescriptionContract/Name != null sont des véritables Service

    2°) Pour les noeuds Service qui ne respecte pas 1°, on récupère le nom de l'opération et on l'ajoute en tant que nouvelle opération dans le premier noeud précèdent qui respecte le 1° (ou IName == plus qu'un seul caractère)

    3°) On supprime les noeuds du 2°


    J'espère que quelqu'un pourra m'aider..

    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 : 48
    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
    inspire toi de ce qu'il y a ici
    http://xml.developpez.com/sources/?page=modifs

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Merci d'avoir répondu..

    Mais malheureusement, je sais toujours pas comment faire.

    Je demande pas la solution (enfin, si quelqu'un est motivé.. ) uniquement la marche à suivre.

    Quelqu'un peut au moins répondre à cette question svp ?

    Comment récupérer le contenu des noeuds suivants de manière conditionel.

    par ex:

    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
     
    <service>
      <description>A</description>
      <opName>operationA1<opName>
    <service> 
     
    <service>
       <description></description>
       <opName>operationA2<opName>
    <service> 
     
    <service>
       <description>B</description>
       <opName>operationB1<opName>
    <service>

    Ici j'aimerai ajouter l'opération A2 au service A et donc obtenir:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <service>
      <description>A</description>
      <opName>operationA1<opName>
      <opName>operationA2<opName>
    <service> 
     
    <service>
       <description>B</description>
       <opName>operationB1<opName>
    <service>


    Merci beaucoup

  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
    Hum, c'était un bon entrainement :
    xml :
    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
    <?xml version="1.0" ?>
    <r>
    <service>
      <description>A</description>
      <opName>operationA1</opName>
    </service> 
     
    <service>
       <description></description>
       <opName>operationA2</opName>
    </service> 
     
    <service>
       <description></description>
       <opName>operationA3</opName>
    </service> 
     
    <service>
       <description>B</description>
       <opName>operationB1</opName>
    </service> 	
    <service>
       <description></description>
       <opName>operationB2</opName>
    </service> 	
    <service>
       <description></description>
       <opName>operationB3</opName>
    </service> 	
    </r>
    xsl :
    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"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output method = "xml"  version="1.0" encoding="utf-8" omit-xml-declaration="no" standalone="no" indent="yes"  />
     
    <xsl:template match="/">
    	<r>
    		<xsl:apply-templates select="//service[description/. != '']"/>
    	</r>    
    </xsl:template>
     
    <xsl:template match="service">
    <service>
    	<xsl:variable name="curDesc" select="description"/>
       <description><xsl:value-of select="$curDesc"/></description>
       <opName><xsl:value-of select="opName"/></opName>
       <xsl:for-each select="following::service[description/.='' and preceding::service[description!=''][1]/description/. = $curDesc]">
       	<opName><xsl:value-of select="opName"/></opName>
       </xsl:for-each>
    </service> 
    </xsl:template>
     
    </xsl:stylesheet>
    sortie :
    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
    <?xml version="1.0" encoding="utf-8" standalone="no"?>
    <r>
    <service>
    <description>A</description>
    <opName>operationA1</opName>
    <opName>operationA2</opName>
    <opName>operationA3</opName>
    </service>
    <service>
    <description>B</description>
    <opName>operationB1</opName>
    <opName>operationB2</opName>
    <opName>operationB3</opName>
    </service>
    </r>

  5. #5
    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
    Bonjour,

    Citation Envoyé par Morbo
    preceding::service[description!=''][1]/description/. = $curDesc
    Attention, ce test est erroné s'il existe plusieurs services avec la même définition entrelacés avec les services sans définition. Autrement dit, tu testes une égalité de noeuds, et non pas une identité (Ce qui n'est pas forcément grave dans ce cas précis mais on manque d'informations pour être affirmatif). Généralement on utilise une technique à base de generate-id() pour tester l'identité.

  6. #6
    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
    Oui, c'est vrai que ma solution fait l'hypothese que la description est unique et je suis pas encore à l'aise avec generated-id (et les keys), mais tu as completement raison, merci pour l'info.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Merci Morbo et GrandFather. Vous me sauvez la vie !!

    Morbo pourrais-tu juste m'expliquer la condition dans la boucle ?

    select="following::service[description/.='' and preceding::service[description!=''][1]/description/. = $curDesc]"


    GrandFather pourrais-tu stp me donner la version avec generated-id (et les keys) ?

    Je sais, j'en demande peut-etre trop.. mais j'ai envie de comprendre.. pas seulement appliquer !!

    Merci encore !!

  8. #8
    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
    following::service
    Sélectionne tous les noeuds "service" qui suivent le noeud courant.

    following::service[description/.='']
    Même chose mais avec un prédicat, seulement les noeud service dont le sous-noeud description est vide.

    Mais ça suffit pas car tu veux seulement les noeud :
    • suivant le courant
    • ayant une decription vide
    • mais seulement les noeuds suivants qui ont comme premier précédent non vide le noeud courant (c'est clair )

    Donc faut ajouter un autre prédicat qui va regarder le premier noeud précédent ayant une description et vérifier que c'est bien le noeud courant :
    preceding::service[description!=''][1]/description/. = $curDesc
    Sinon on ajouterait à chaque noeud non vide, les noeud vides

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Merci Morbo..

    J'ai enfin compris...

    Quelqu'un aurait la gentillesse de poster la solution avec la génération des id ?



    merci..

  10. #10
    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
    La variante avec test d'identité :
    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">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:template match="Services">
            <xsl:copy>
                <xsl:apply-templates select="Service[normalize-space(DescriptionContract/Name) != '']"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="Service">
            <xsl:copy>
                <xsl:copy-of select="DescriptionContract"/>
                <InterfaceContract>
                    <xsl:copy-of select="InterfaceContract/IName"/>
                    <xsl:copy-of select="InterfaceContract/OpName"/>
                    <xsl:for-each select="following-sibling::Service[normalize-space(DescriptionContract/Name) = '' and generate-id(preceding-sibling::Service[normalize-space(DescriptionContract/Name) != ''][1]) = generate-id(current())]">
                        <xsl:copy-of select="InterfaceContract/OpName"/>
                    </xsl:for-each>
                </InterfaceContract>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    Il n'est pas nécessaire d'utiliser l'indexation avec xsl:key dans ce cas, puisque le regroupement des noeuds se fait selon leur position dans le document et non selon une valeur clé.

    Un détail : il vaut mieux privilégier la syntaxe description à description/. (raccourci de description/self::node()), moins alambiquée et moins redondante à mon avis.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    merci GrandFather


    J'ai eu réponses à toutes mes questions..


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

Discussions similaires

  1. [XSLT] Problème affichage d'un noeud
    Par Mselle dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 15/01/2007, 11h45
  2. [XSLT] gérer l'absence de noeud
    Par gojira dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 19/10/2006, 16h20
  3. [XSLT] Connaître le nombre de noeuds renvoyés
    Par mc_sid dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 23/11/2005, 15h39
  4. [XSLT]Problème de séléction du noeud courrant
    Par virgul dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 16/08/2005, 07h51
  5. XSLT > Acceder un élement du noeud suivant
    Par soize dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 10/01/2005, 15h33

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