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 :

parser le contenu de deux fichiers XML


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut parser le contenu de deux fichiers XML
    Bonjour,
    J'ai un gros problème 'a résoudre et j'aimerais etre sure de me lancer dans la bonne voie.

    J'ai deux fichiers xml.
    Le premier d'entre eux se presente comme ceci:

    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
    <balise0>
    	<balise1>
    		<balise2>
    			<balise3>opopop</balise3>
    			<balise3>gnagnagna</balise3>
    		</balise2>
    		<balise4>
    			<balise1>blablabla</balise1>
    			<balise5>didadidadou</balise5>
    		</balise4>
    		<balise6>
    			<balise7>
    				<balise1>pfioupioupiou</balise1>
    			</balise7>
    		</balise6>
    	</balise1>
    </balise0>
    Il y a une quantite astronomique de balises differentes, en fait elles ne sont que tres peu repetees dans le document pour la bonne raison qu'une balise est en fait une information.
    En fait, chaque balise a un "type", elle est soit un segment, soit un groupe, soit un composite, soit une data, et le document est forme comme ceci:

    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
    <groupe>
    	<groupe>
    		<segment>
    			<data>opopop</data>
    			<data>gnagnagna</data>
    		</segment>
    		<segment>
    			<data>blablabla</data>
    			<data>didadidadou</data>
    		</segment>
    		<segment>
    			<composite>
    				<data>pfioupioupiou</data>
    			</composite>
    		</segment>
    	</groupe>
    </groupe>
    (c'est le m^eme document que le premier exemple)

    On a donc toujours la meme structure:
    (n)groupe -> 1 segment -> (n)composite -> 1 data.

    Je dois trouver une maniere de representer cette information, je dois pour cela savoir pour chaque balise si c'est un segment, un composite, un groupe.

    Je sais cela grace au 2eme document XML qui se presente comme ceci:


    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
    <GROUPS>
    	<GROUP ID="532421" SMARTNAME="balise1"  DESCRIPTI... infos diverses concernant la balise, qu'il va falloir integrer dans le HTML final>
    		<SEGMENTREF ID="52452" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		<GROUP ID="676144" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    			<SEGMENTREF ID="5445" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		</GROUP>
    	</GROUP>
    </GROUPS>
    <SEGMENTS>
    	<SEGMENT ID="241254" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		<COMPOSITEREF ID="25454" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		<DATA ID="245005" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    			<CODESETS>
    				<CODESET TAG="pfioupioupiou" DESCRIPTION="explication de la valeur de la data"/>
    				<CODESET TAG="blablabla" DESCRIPTION="explication de la valeur de la data"/>
    				<CODESET TAG="opopop" DESCRIPTION="explication de la valeur de la data"/>
    			</CODESETS>
    		</DATA>
    	</SEGMENT>
    </SEGMENTS>
    <COMPOSITES>
    	<COMPOSITE ID="8637" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		<DATA ID="23574254" SMARTNAME="balise1"  DESCRIPTI... infos diverses qu'il va falloir integrer dans le HTML final>
    		<CODESETS>
    			<CODESET TAG="didadidadou" DESCRIPTION="explication de la valeur de la data"/>
    		</CODESETS>
    		</DATA>
    </COMPOSITES>
    Ce document nous dit:
    - de quel "type" est chaque balise du document 1 (la balise correspond au type de la balise du document 1, smartname correspond au nom de la balise du document 1)
    - les informations correspondantes aux noms des balises
    - la traduction des valeurs ("pfioupioupiou", "opopop", "gnagnagna"... cette traduction est contenue dans CODSET)


    Voila, en gros, mon travail. Il va donc falloir que je combine les deux documents. Le rendu sera une page HTML avec la m^eme structure que le premier document, et avec les informations contenues dans le deuxieme document.
    Je pensais donc mettre les informations du document 2 dans un tableau ou on aurait:
    nom de la balise | type de balise | description
    Puis dans un second temps integrer cela 'a la presentation HTML faite grace 'a XSLT.

    En fait une fois que j'aurai le tableau "nom de la balise | type de balise | description" je pourrai peut etre parser le contenu du document 1 pour obtenir par exemple:

    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
    <groupe VALUE="balise0" DESCRIPTION= ...........>
    	<groupe VALUE="balise1" DESCRIPTION= ...........>
    		<segment VALUE="balise2" DESCRIPTION= ...........>
    			<data VALUE="balise3" DESCRIPTION= ...........>opopop</data>
    			<data VALUE="balise3" DESCRIPTION= ...........>gnagnagna</data>
    		</segment>
    		<segment>
    			<data VALUE="balise1" DESCRIPTION= ...........>blablabla</data>
    			<data VALUE="balise5" DESCRIPTION= ...........>didadidadou</data>
    		</segment>
    		<segment>
    			<composite VALUE="balise7" DESCRIPTION= ...........>
    				<data VALUE="balise1" DESCRIPTION= ...........>pfioupioupiou</data>
    			</composite>
    		</segment>
    	</groupe>
    </groupe>
    Ce qui sera plus facile 'a presenter en HTML


    Cela (la recuperation du contenu du document2 dans un tableau) est faisable avec DOM par exemple, n'est ce pas? Ou simpleXML, sans doute plus simple... Est ce que vous me conseillez une technologie particuliere? Est ce que ma maniere de proceder vous semble correcte?
    (ne connaissant pas encore grand chose de tout cela, meme si je me renseigne depuis une semaine, je fais appel 'a des experts!)
    J'espere que vous aurez 'a peu pres compris mon probleme,

    Un enorme merci d'avance!

  2. #2
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Je vais donc poser une question un peu plus breve.

    Si je me retrouve avec d'un cote la structure
    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
    <balise0>
    	<balise1>
    		<balise2>
    			<balise3>opopop</balise3>
    			<balise3>gnagnagna</balise3>
    		</balise2>
    		<balise4>
    			<balise1>blablabla</balise1>
    			<balise5>didadidadou</balise5>
    		</balise4>
    		<balise6>
    			<balise7>
    				<balise1>pfioupioupiou</balise1>
    			</balise7>
    		</balise6>
    	</balise1>
    </balise0>
    et de l'autre un tableau obtenu grace 'a simpleXML, contenant
    balise1 | groupe| description | etc...
    balise2 | segment| description | etc
    balise3 | data| description | etc
    balise4 | composite| description | etc
    et que je veux que le premier document se transforme en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <groupe value = "balise0" description = "blablabla">
    	<groupe value = "balise1" description = "blablabla">
    		<segment value = "balise2" description = "blablabla">
    			<data value = "balise3" description = "blablabla">opopop</balise3>
    etc...


    est ce que je peux faire ca grace 'a DOM en PHP? Est ce que ca vous parait etre une bonne solution?

  3. #3
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Je ne connais pas du tout la gestion du XML en PHP et malheureusement, ceux qui connaissent vont rarement dans le forum XML.

    Par contre, ce que tu veux faire (si j'ai bien tout compris ) est totalement faisable en XSLT.

    Pour celà, il faut que tes fichiers XML existent réellement (que ce ne soient pas juste des flux) et que tu utilises la fonction XSL document() pour les charger (en tout cas au moins un des deux).

    Une fois que tu as accès aux 2 documents dans la même feuille de style, faire le mapping est relativement simple.

    Je te propose que tu nous montres comment tu penses coder ça, que tu nous dises où ça plante (si ça plante) et qu'on t'aide à l'améliorer/corriger si besoin.
    Ca c'est si tu penses faire tout le traitement en XSLT.

    Par contre si tu comptes faire un traitement en PHP, je te conseille de demander sur le forum PHP dédié à ça.

  4. #4
    Membre émérite
    Avatar de polymorphisme
    Homme Profil pro
    Publishing
    Inscrit en
    Octobre 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Publishing
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2009
    Messages : 1 460
    Points : 2 372
    Points
    2 372
    Par défaut
    Bonjour,

    c'est clairement faisable avec XSLT
    Dans tous les cas, ton idée de tableau n'est pas du tout utile
    et ne fait que complexifier ton programme.

    Il te faut commencer par renommer tes éléments à partir de l'attribut value.
    Puis effectuer ta transformation données vers html.
    Dans un soucis de simplicité, tu peux commencer par écrire ces deux étapes dans des fichiers différents.

  5. #5
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Merci beaucoup. En fait je ne suis pas du tout 'a l'aise avec XSLT, ça m'est totalement inconnu et je patauge dans la semoule depuis une semaine, je n'avance 'a rien.
    Mais je vais essayer de suivre votre conseil, et donc commencer par le renommage. Par contre je pense que vous n'en avez pas fini avec mes questions

  6. #6
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Comme prévu je galère pas mal!

    Voila ce que j'aimerais faire: comme si j'avais ceci

    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
    <groupe VALUE="balise0" DESCRIPTION= "trgbcxv">
    	<groupe VALUE="balise1" DESCRIPTION= "hfxb">
    		<segment VALUE="balise2" DESCRIPTION="grbv">
    			<data VALUE="balise3" DESCRIPTION= "breb">opopop</data>
    			<data VALUE="balise3" DESCRIPTION= "brfb">gnagnagna</data>
    		</segment>
    		<segment>
    			<data VALUE="balise1" DESCRIPTION= "bre">blablabla</data>
    			<data VALUE="balise5" DESCRIPTION= ".thendxv">didadidadou</data>
    		</segment>
    		<segment>
    			<composite VALUE="balise7" DESCRIPTION= "tygndc">
    				<data VALUE="balise1" DESCRIPTION= "yhtf">pfioupioupiou</data>
    				<composite VALUE="balise7" DESCRIPTION= "tygndc">
    					<data VALUE="balise1" DESCRIPTION= "ymrgc">jhybgkb</data>
    				</composite>
    			</composite>
    		</segment>
    	</groupe>
     
    </groupe>
    et qu'en faisant
    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
     
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
     
    <xsl:template match="/">
    	<html><body>
    		<xsl:apply-templates/>
    	</body></html>
    </xsl:template>
     
     
    <xsl:template match="/">
    <p>OPOPOPPPPPP</p>
    <table border="1" cellspacing="0" cellpadding="3">
    		<tr bgcolor="#FFFF00">
    			<td>Data</td>
    			<td>Tag</td>
    			<td>Description</td>
    		</tr>
     
     
    <xsl:for-each select="//groupe">
    	<xsl:for-each select="segment">
    		<xsl:for-each select="data">
    			<tr>
    				<td><xsl:value-of select="."/></td>
    				<td><xsl:value-of select="@VALUE"/></td>
    				<td><xsl:value-of select="@DESCRIPTION"/></td>
    			</tr>
    		</xsl:for-each>	
    	</xsl:for-each>
     
    	<xsl:for-each select="segment//composite">
    			<xsl:for-each select="data">
    				<tr>
    					<td><xsl:value-of select="."/></td>
    					<td><xsl:value-of select="@VALUE"/></td>
    					<td><xsl:value-of select="@DESCRIPTION"/></td>
    				</tr>
    			</xsl:for-each>	
    	</xsl:for-each>
     
     
    </xsl:for-each>
    </table>
    </xsl:template>
    </xsl:stylesheet>
    j'obtienne
    Nom : exTab.jpg
Affichages : 214
Taille : 14,6 Ko

    Sauf que je n'ai pas le premier document, j'ai 'a la place les 2 que voici ensuite.
    je suis donc vos conseils et j'essaie de mapper les deux docs XML:

    la structure de
    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
    <?xml version="1.0" encoding="UTF-8" ?> 
    <balise0>
    	<balise1>
    		<balise2>
    			<balise3>opopop</balise3>
    			<balise3>gnagnagna</balise3>
    		</balise2>
    		<balise4>
    			<balise1>blablabla</balise1>
    			<balise5>didadidadou</balise5>
    		</balise4>
    		<balise6>
    			<balise7>
    				<balise8>pfioupioupiou</balise8>
    			</balise7>
    		</balise6>
    	</balise1>
    </balise0>

    avec les informations de
    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
     
    <GROUPS>
    	<GROUP ID="532421" SMARTNAME="balise1"  DESCRIPTION= "balise numero 1">
    		<SEGMENTREF ID="52452" SMARTNAME="balise2"  DESCRIPTION= "balise numero 2"/>
    		<GROUP ID="676144" SMARTNAME="balise3"  DESCRIPTION= "balise numero 3">
    			<SEGMENTREF ID="5445" SMARTNAME="balise1"  DESCRIPTION= "balise numero 1"/>
    		</GROUP>
    	</GROUP>
    </GROUPS>
    <SEGMENTS>
    	<SEGMENT ID="241254" SMARTNAME="balise4"  DESCRIPTION= "balise numero 4">
    		<COMPOSITEREF ID="25454" SMARTNAME="balise5"  DESCRIPTION= "balise numero 5"/>
    		<DATA ID="245005" SMARTNAME="balise6"  DESCRIPTION= "balise numero 6">
    			<CODESETS>
    				<CODESET TAG="pfioupioupiou" DESCRIPTION="explication de la valeur de pfioupioupiou"/>
    				<CODESET TAG="blablabla" DESCRIPTION="explication de la valeur de blablabla"/>
    				<CODESET TAG="opopop" DESCRIPTION="explication de la valeur de opopop"/>
    			</CODESETS>
    		</DATA>
    	</SEGMENT>
    </SEGMENTS>
    <COMPOSITES>
    	<COMPOSITE ID="8637" SMARTNAME="balise7"  DESCRIPTION= "balise numero 7"/>
    		<DATA ID="23574254" SMARTNAME="balise8"  DESCRIPTION= "balise numero 8">
    		<CODESETS>
    			<CODESET TAG="didadidadou" DESCRIPTION="explication de la valeur de didadidadou"/>
    		</CODESETS>
    		</DATA>
    </COMPOSITES>
    pour cela j'ai fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     	$XmlData = "newExemple.xml";
    	$XslData = "new2.xsl";
    et le 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
    23
    24
    25
    26
    27
    28
    29
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
     
    <xsl:template match="/">
    	<html><body>
    		<xsl:apply-templates/>
    	</body></html>
    </xsl:template>
     
    <xsl:template match="/">
    <p>OPOPOPPPPPP</p>
    <table border="1" cellspacing="0" cellpadding="3">
    		<tr bgcolor="#FFFF00">
    			<td>Data</td>
    			<td>Description</td>
    		</tr>
     
    		<xsl:variable name="nomBalise" select="local-name(.)" />
    <xsl:for-each select="document('newStruct.xml')//GROUP[@SMARTNAME=$nomBalise]">
    			<tr>
    				<td><xsl:value-of select="."/></td>
    				<td><xsl:value-of select="document('newStruct.xml')//GROUPE[@SMARTNAME=$nomBalise]/@DESCRIPTION "/></td>
    			</tr>
    </xsl:for-each>		
     
    </table>
    </xsl:template>
    </xsl:stylesheet>
    J'essaie de faire ce que j'ai explique dans mon premier post. jusqu'ici, j'aimerais simplement recuperer la description de balise1, qui est un "group".

    Mais je ne sais pas vraiment comment m'y prendre, est ce que le fond de ma méthode est bon?

    Et est ce que le fait qu'il y ait des balises "uniques" va poser probleme?

  7. #7
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Le "fond" de ta méthode est correct, mais pas le code.

    Bon d'abord, pour la forme, avoir deux templates qui matchent exactement le même élément sans aucune précision supplémentaire c'est très dangereux (en plus de ne pas être joli).

    De plus dans ton cas tu peux très bien les mettre au même niveau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:template match="/">
    	<html><body>
    		<!--xsl:apply-templates/  => pas beau -->
    		<!-- ton traitement ici -->
    	</body></html>
    </xsl:template>
    Ensuite, dans le deuxième XSL que tu as montré, tu as apparement confondu ton document actuel avec le document "lié".
    Le for-each doit se faire sur le contenu du document actuel et la recherche sur celui qui est ouvert par la suite.

    Le mieux étant de passer par des templates :
    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
    <xsl:template match="/">
    	<html>
    	<body>
    		<table border="1" cellspacing="0" cellpadding="3">
    			<tr bgcolor="#FFFF00">
    				<td>Data</td>
    				<td>Tag</td>
    				<td>Description</td>
    			</tr>
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="document('newStruct.xml')"/>
    			</xsl:apply-templates>
    		</table>
    	</body>
    	</html>
    </xsl:template>
     
    <xsl:template match="*">
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />
    	<tr>
    		<td><xsl:value-of select="."/></td>
    		<td><xsl:value-of select="$nomBalise"/></td>
    		<td><xsl:value-of select="$structure/descendant::*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></td>
    	</tr>
    </xsl:template>
    J'ai pas testé mais ça devrait plus ressembler à ça.

  8. #8
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    exact pour les templates, ça résulte de tous mes test un peu idiots pour apprendre le XML

    Merci beaucoup, tu viens de m'apprendre tout plein de trucs en un post! Maintenant je me lance dans le parcours en profondeur a priori, comme je ne connais pas les noms des balises.

    (remarque idiote, mais c'est dingue comme il est difficile de se détacher de la technique pour réfléchir ne serait-ce qu'un tout petit peu au fond, quand on apprend des nouveaux concepts. Je me sens toujours assez débile après avoir lu vos réponses, alors que j'ai quand même passé quelques heures sur le problème... En tous cas un grand merci!)

  9. #9
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Bonjour,
    Encore moi! Cette fois je touche le bout, enfin j'espere... Mais encore un petit souci.
    Voila ce que je veux avoir comme "type" de document XML (associe 'a un fichier CSS):


    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
    <html>
    <link rel="stylesheet" type="text/css" href="edi_style.css" />
    <body>
    <h2>MESSAGE: <span class="mouseover">FUNCTION=</span>"Retrieve Date Info"</h2>
    <p class="message_desc">message type="44364" </p>
    <p class="message_meaning"><span class="mouseover">MEANING=</span>"the message means that gnagnagna</p>
    <div class="group">
    	<div class="group_descr">
    		<p class="group_smartname">group smart</p>
    		<p class="group_description">group desc</p>
    	</div>
    	<br/>
    	<div class="segment">
    		<div class="segment_descr">
    			<p class="segment_smartname">segment smartname</p>
    			<p class="segment_description">segment desc.</p>
    			<div class="composite">
    				<div class="composite_descr">
    					<p class="composite_smartname">composite smart</p>
    					<p class="composite_description">composite desc</p>
    					<div class="data">
    						<table>
    							<tr> <!-- ligne du tableau-->
    								<th>Tag Name</th>
    								<th>Value</th>
    								<th>Value translation</th>
    								<th>Tag Description</th>
    							</tr>
    							<tr> 
    								<td>balise1</td>
    								<td>5341021</td>
    								<td>code de balise1 </td>
    								<td>balise1 means ...</td>
    							</tr>
    							<tr> 
    								<td>balise2</td>
    								<td>53131</td>
    								<td> code de balise2</td>
    								<td>balise2 means ...</td>
    							</tr>
    						</table>
    					</div>
    				</div>
    			</div>
    		</div>
    	</div><br/>
    </div><br/>
    </div>
    </body>
    </html>

    Pour donner ceci:
    Nom : ex forum.JPG
Affichages : 150
Taille : 42,2 Ko

    Et pour ce faire, Voici donc mon fichier XSLT. (pas termine, je n'ai pas fait le template opCOMPOSITE ni la partie MESSAGE, mais le reste ne fonctionne pas encore...)

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
     
     
    <xsl:template match="/">
    	<html>
    	<link rel="stylesheet" type="text/css" href="style.css" />
    	<body>
    		<xsl:apply-templates match="*/" mode = "opGROUP">																	<!-- template opGROUP: la premiere balise est un groupe -->
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>         									<!-- passe comme param au template le document XML -->
    		</xsl:apply-templates>
    	</body>
    	</html>
    </xsl:template>
     
    <xsl:template match="*" mode = "opGROUP">		
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />																		  	<!-- ex: balise1 -->
    	<xsl:if test="local-name($structure//*[@SMARTNAME=$nomBalise])='GROUP'">															<!-- si la balise est bien de type "GROUP"  -->
    		<div class="group">
    			<div class="group_descr">
    				<p class="group_smartname"><xsl:value-of select="$nomBalise"/></p>														<!-- ex:balise1 -->							
    				<p class="group_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>  			<!-- ex:description de la balise1 -->
    				<xsl:variable name="nomBaliseFille" select="local-name(node())" />
    				<xsl:choose>				<!-- soit la balise contenue est 'a nouveau un groupe, auquel cas on reappelle le meme template, soit c'est un segment, auquel cas on appelle le template opSEGMENT -->
    					<xsl:when test="local-name($structure//*[@SMARTNAME=$nomBaliseFille])='GROUP'">          
    						<xsl:apply-templates  match="/|node()" mode = "opGROUP">							<!-- fonctionne visiblement bien: si je l'enleve je n'ai plus de recursivite -->
    							<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- c'est un groupe : on rappelle le meme template -->
    						</xsl:apply-templates>
    					</xsl:when>       
     
    					<xsl:when test="local-name($structure//*[@SMARTNAME=$nomBaliseFille])='SEGMENT' or 'SEGMENTREF'  ">  <!-- 17.25 c est ici que ca bug. il ne fait pas le when: si j'inverse c'est ok -->
    						<h1>TEST</h1>
    						<xsl:apply-templates  match="/|node()" mode = "opSEGMENT">
    							<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- c'est un segment: on appelle le template opSEGMENT -->
    						</xsl:apply-templates>
    					</xsl:when>
     
    					<xsl:otherwise> 
    						<h1>TEST2</h1>
    					</xsl:otherwise> 
    				</xsl:choose>
    			</div><br/>
    		</div>
    	</xsl:if>
     
     
    </xsl:template>
     
    <xsl:template match="*" mode = "opSEGMENT">														  				<!-- template opSEGMENT: si on a des segments 'a l'interieur du group -->
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />								  					<!-- ex: balise1 -->
    	<xsl:if test="local-name($structure//*[@SMARTNAME=$nomBalise])='SEGMENT' or 'SEGMENTREF'">
    		<div class="segment">
    			<div class="segment_descr">
    				<p class="segment_smartname"><xsl:value-of select="$nomBalise"/></p>
    				<p class="segment_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    				<xsl:choose>																					 <!-- on a soit un composite, soit une data -->
    					<xsl:when test="local-name(node())='DATA'">
    						<xsl:apply-templates  match="*|node()" mode = "opDATA">
    							<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- si on a data, on appelle le template opDATA -->
    						</xsl:apply-templates>
    					</xsl:when>
    					<xsl:when test="local-name($structure//*[@SMARTNAME=$nomBalise])='COMPOSITE' or 'COMPOSITEREF'">
    						<xsl:apply-templates  match="*/*" mode = "opCOMPOSITE">
    							<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- si on a composite, on appelle opCOMPOSITE -->
    						</xsl:apply-templates>
    					</xsl:when>
    				</xsl:choose>
    			</div>
    		</div><br/>
    	</xsl:if>
    </xsl:template>
     
     
     
     
    <xsl:template match="*" mode = "opDATA">														  <!-- template opDATA: si on a des data -->
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />								  <!-- ex: flightInfoData -->
    	<xsl:if test="local-name($structure//*[@SMARTNAME=$nomBalise])='DATA'">
    		<table border="1" cellspacing="0" cellpadding="3">
    			<tr>
    				<th>Tag Name</th>
    				<th>Type</th>
    				<th>Tag Description</th>
    				<th>Value</th>
    			</tr>
    			<tr>
    				<td><xsl:value-of select="$nomBalise"/></td>
    				<td><xsl:value-of select="local-name($structure//*[@SMARTNAME=$nomBalise])"/></td>    <!-- on va chercher le type de la balise dans newStruct.xml -->
    				<td><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></td>   <!-- on va chercher la description de la balise dans newStruct.xml -->
    				<td><xsl:value-of select="."/></td>													  <!-- on va chercher la valeur -->
    			</tr>
    		</table>
    	</xsl:if>
    	<xsl:apply-templates  match="*/*" mode = "opDATA">
    		<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- recursivite: continue en profondeur d'abord -->
    	</xsl:apply-templates>
    </xsl:template>
     
     
     
    </xsl:stylesheet>
    Je me suis donc penchee sur les parties Group (il peut y avoir plusieurs groupes imbriques), segment (le fils d'un segment est soit un composite, soit une data) et Data (dans un tableau)
    Le probleme se trouve selon moi dans le template opGROUP et plus particulierement ici

    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
    <xsl:choose>				
    	<xsl:when test="local-name($structure//*[@SMARTNAME=$nomBalise])='GROUP'">          
    		<xsl:apply-templates  match="*|node()" mode = "opGROUP">							<!-- fonctionne visiblement bien: si je l'enleve je n'ai plus de recursivite -->
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- c'est un groupe : on rappelle le meme template -->
    		</xsl:apply-templates>
    	</xsl:when>       
     
    	<xsl:when test="local-name($structure//*[@SMARTNAME=$nomBalise])='SEGMENT' or 'SEGMENTREF'  ">  <!-- 17.25 c est ici que ca bug. il ne fait pas le when: si j'inverse c'est ok -->
    		<h1>TEST</h1>
    		<xsl:apply-templates  match="*|node()" mode = "opSEGMENT">
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>                 <!-- c'est un segment: on appelle le template opSEGMENT -->
    		</xsl:apply-templates>
    	</xsl:when>
    	<xsl:otherwise> 
    		<h1>TEST2</h1>
    	</xsl:otherwise> 
    </xsl:choose>
    Comme dit en commentaire, le second "when" ne fonctionne pas.
    ici j'ai ceci:

    Nom : ex forum 2.JPG
Affichages : 229
Taille : 10,9 Ko

    et si j'inverse les 2 when j'ai cela:

    Nom : ex forum 3.JPG
Affichages : 232
Taille : 18,6 Ko

    En fait il ne tient meme pas compte de l'instruction "est ce un segment?" puisqu'il affiche toujours balise3, alors que c'est un groupe..

    (au passage, ici du coup il ne m'appelle pas non plus le template opDATA non plus mais il m'affiche toutes les donnees et je ne vois pas du tout pourquoi, mais peu importe pour l'instant)

    est ce que vous voyez ou' se situe l'erreur? je pense qu'il y en a une au niveau du when et une autre au niveau du test "est ce bien un segment?"

    Merci beaucoup d'avance!!

  10. #10
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    j'ai trouve!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:variable name="nomBaliseFille" select="local-name(child::*)" />
    (je me jurais pourtant d'avoir deja essaye...)

  11. #11
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Apparement tu as quelques soucis avec le XPath.

    Je te conseille vivement de lire cette page : http://www.w3schools.com/xpath/xpath_syntax.asp ainsi que l'ensemble du site concernant XPath (principalement les axes et les opérateurs).

    Bon déjà tous tes match="*|node()" sont totalement inutile car "*" signifie tous les noeuds de type élément et "node()" signifie tous les noeuds (élément, attribut, commentaire, ...). Donc clairement "node()" est un surensemble de "*" et il n'y a donc pas lieu d'avoir les deux.

    Ensuite, ton test <xsl:when test="local-name($structure//*[@SMARTNAME=$nomBalise])='SEGMENT' or 'SEGMENTREF'"> passait même quand tu n'étais pas dans un segment car il est tout le temps vrai.
    En effet il teste si :
    - $structure//*[@SMARTNAME=$nomBalise]) = 'SEGMENT' est vrai
    ou si
    - 'SEGMENTREF' est vrai (ce qui est tout le temps le cas).

    Enfin, il n'est pas nécessaire d'utiliser des templates avec "mode" pour ton problème, même si c'était une bonne idée.
    A mon avis le mieux serait d'écrire un template qui match tous les éléments et qui redispatch vers d'autres templates en fonction du traitement à effectuer.
    Voilà à quoi ça pourrait ressembler :

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
     
    <xsl:template match="/">
    	<html>
    	<link rel="stylesheet" type="text/css" href="style.css" />
    	<body>
    		<xsl:apply-templates match="*">
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>
    		</xsl:apply-templates>
    	</body>
    	</html>
    </xsl:template>
     
    <xsl:template match="*">
    	<xsl:param name="structure" />
     
    	<xsl:variable name="nomBalise" select="local-name(.)" />
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
     
    	<xsl:choose>
    		<xsl:when test="$typeBalise = 'GROUP'">
    			<!-- traitement à faire pour les éléments de type GROUP : -->
    			<!-- L'élément actuel (. ou current())est de type GROUP -->
    			<xsl:call-template name="opGROUP"> <!-- on appel le template gérant les éléments de type GROUP -->
    				<xsl:with-param name="structure" select="$structure"/> <!-- on réutilise le document $structure, pas besoin de le ré-ouvrir -->
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:when test="$typeBalise = 'SEGMENT' or $typeBalise = 'SEGMENTREF'"> <!-- on refait bien le test pour SEGMENTREF -->
    			<xsl:call-template name="opSEGMENT">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:when test="$typeBalise = 'COMPOSITE' or $typeBalise = 'COMPOSITEREF'">
    			<xsl:call-template name="opCOMPOSITE">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:call-template>
    		<xsl:when test="$typeBalise = 'DATA'">
    			<xsl:call-template name="opDATA">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:otherwise>
    			<!-- Il y'a un problème -->
    		</xsl:otherwise>
    	</xsl:choose>
    </xsl:template>
     
    <xsl:template name="opGROUP">
    	<xsl:param name="structure" />
     
    	<!-- traitement à faire pour les éléments de type GROUP : -->
    	<!-- L'élément actuel (. ou current())est de type GROUP -->
    	<div class="group">
    		<div class="group_descr">
    			<p class="group_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="group_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<!-- On traite tous les éléments (*) fils de l'élément actuel -->
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:apply-templates>
    		</div><br/>
    	</div>
    </xsl:template>
     
    <xsl:template name="opSEGMENT">
    	<xsl:param name="structure" />
     
    	<div class="segment">
    		<div class="segment_descr">
    			<p class="segment_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="segment_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:apply-templates>
    		</div>
    	</div><br/>
    </xsl:template>
     
    <xsl:template name="opDATA">
    	<xsl:param name="structure"/>
     
    	<table border="1" cellspacing="0" cellpadding="3">
    		<tr>
    			<th>Tag Name</th>
    			<th>Type</th>
    			<th>Tag Description</th>
    			<th>Value</th>
    		</tr>
    		<tr>
    			<td><xsl:value-of select="$nomBalise"/></td>
    			<td><xsl:value-of select="local-name($structure//*[@SMARTNAME=$nomBalise])"/></td>
    			<td><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></td>
    			<td><xsl:value-of select="."/></td>
    		</tr>
    	</table>
    </xsl:template>
     
    <xsl:template name="opCOMPOSITE">
    	<xsl:param name="structure"/>
     
    	<!-- TODO -->
    </xsl:template>
     
    </xsl:stylesheet>

  12. #12
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Merci beaucoup c'est vrai que c'est bien plus joli, voila qui me donne ça:

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
     
    <xsl:template match="/">
    	<html>
    	<link rel="stylesheet" type="text/css" href="style.css" />
    	<body>
    		<xsl:apply-templates match="*">
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>
    		</xsl:apply-templates>
    	</body>
    	</html>
    </xsl:template>
     
    <xsl:template match="*">
    	<xsl:param name="structure" />
     
    	<xsl:variable name="nomBalise" select="local-name(.)" />
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
     
    	<xsl:choose>
    		<xsl:when test="$typeBalise = 'GROUP'">
    			<!-- traitement à faire pour les éléments de type GROUP : -->
    			<!-- L'élément actuel (. ou current())est de type GROUP -->
    			<xsl:call-template name="opGROUP"> <!-- on appel le template gérant les éléments de type GROUP -->
    				<xsl:with-param name="structure" select="$structure"/> <!-- on réutilise le document $structure, pas besoin de le ré-ouvrir -->
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:when test="$typeBalise = 'SEGMENT' or $typeBalise = 'SEGMENTREF'"> <!-- on refait bien le test pour SEGMENTREF -->
    			<xsl:call-template name="opSEGMENT">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:when test="$typeBalise = 'COMPOSITE' or $typeBalise = 'COMPOSITEREF'">
    			<xsl:call-template name="opCOMPOSITE">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:call-template>
    		</xsl:when>
    		<xsl:when test="$typeBalise = 'DATA'">
    			<table border="1" cellspacing="0" cellpadding="3">
    				<tr>
    					<th>Tag Name</th>
    					<th>Type</th>
    					<th>Tag Description</th>
    					<th>Value</th>
    				</tr>
    				<xsl:call-template name="opDATA">
    					<xsl:with-param name="structure" select="$structure"/>
    				</xsl:call-template>
    			</table>
    		</xsl:when>
    		<xsl:otherwise>
     
    		</xsl:otherwise>
    	</xsl:choose>
    </xsl:template>
     
    <xsl:template name="opGROUP">
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />	
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
    	<!-- traitement à faire pour les éléments de type GROUP : -->
    	<!-- L'élément actuel (. ou current())est de type GROUP -->
    	<div class="group">
    		<div class="group_descr">
    			<p class="group_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="group_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<!-- On traite tous les éléments (*) fils de l'élément actuel -->
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:apply-templates>
    		</div><br/>
    	</div>
    </xsl:template>
     
    <xsl:template name="opSEGMENT">
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />	
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
    	<div class="segment">
    		<div class="segment_descr">
    			<p class="segment_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="segment_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:apply-templates>
    		</div>
    	</div><br/>
    </xsl:template>
     
    <xsl:template name="opDATA">
    	<xsl:param name="structure"/>
     	<xsl:variable name="nomBalise" select="local-name(.)" />	
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
     
    		<tr>
    			<td><xsl:value-of select="$nomBalise"/></td>
    			<td><xsl:value-of select="local-name($structure//*[@SMARTNAME=$nomBalise])"/></td>
    			<td><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></td>
    			<td><xsl:value-of select="."/></td>
    		</tr>
     
    </xsl:template>
     
    <xsl:template name="opCOMPOSITE">
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />	
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
    	<div class="composite">
    		<div class="composite_descr">
    			<p class="composite_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="composite_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<xsl:apply-templates match="*">
    				<xsl:with-param name="structure" select="$structure"/>
    			</xsl:apply-templates>
    		</div>
    	</div><br/>
    </xsl:template>
     
    </xsl:stylesheet>
    CEPENDANT il y a encore un petit souci
    Nom : ex forum 4.JPG
Affichages : 241
Taille : 88,3 Ko
    J’obtiens cela. Je sais que c'est juste de l'algorithmie mais avec les balises imbriquees j'arrivais
    Nom : ex forum 5.JPG
Affichages : 257
Taille : 15,3 Ko

    du coup ca ferait assez moche de reimbriquer des balises filles DATA dans les segments et composite quand on a une DATA juste apres... mais j'ai pas d'autre option pour l'instant. je pense juste, est ce qu'il serait possible de mettre une sorte de if ce n'est pas la premiere DATA, alors je ne mets pas l'entete?

    du genre "si la balise qu'a parcouru <xsl:template match="*"> juste avant est egalement de type DATA alors je fais un traitement different"

    sinon un genre de flag? dans chaque template... mmmm...

  13. #13
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Citation Envoyé par getrude Voir le message
    Merci beaucoup c'est vrai que c'est bien plus joli
    C'est surtout correct.

    Pour ce qui est de l'entête du tableau, il faut la déclarer dans l'élément parent (à ce que j'ai compris dans les segments) et laisser le traitement tel qu'il est dans les DATA/COMPOSITE :
    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
    <xsl:template name="opSEGMENT">
    	<xsl:param name="structure" />
    	<xsl:variable name="nomBalise" select="local-name(.)" />	
    	<xsl:variable name="typeBalise" select="local-name($structure//*[@SMARTNAME=$nomBalise])"/>
    	<div class="segment">
    		<div class="segment_descr">
    			<p class="segment_smartname"><xsl:value-of select="$nomBalise"/></p>
    			<p class="segment_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    			<xsl:choose>
    				<xsl:when test="descendant::*[$structure//DATA/@SMARTNAME = local-name()]">
    					<table border="1" cellspacing="0" cellpadding="3">
    						<tr>
    							<th>Tag Name</th>
    							<th>Type</th>
    							<th>Tag Description</th>
    							<th>Value</th>
    						</tr>
    						<xsl:apply-templates match="*">
    							<xsl:with-param name="structure" select="$structure"/>
    						</xsl:apply-templates>
    					</table>
    				</xsl:when>
    				<xsl:otherwise>
    					<xsl:apply-templates match="*">
    						<xsl:with-param name="structure" select="$structure"/>
    					</xsl:apply-templates>
    				</xsl:otherwise>
    			</xsl:choose>
    		</div>
    	</div><br/>
    </xsl:template>

  14. #14
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    merci beaucoup, c’était plus que de simples suggestions la, vous m'avez carrément donné tous les codes c'est vraiment sympa d'avoir réfléchi autant 'a mon problème! j'aurais perdu un temps encore plus fou sans vous 2, merci pour tout

  15. #15
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    C'est aussi à ça que sert ce forum.

    Lorsqu'on débute, il est parfois préférable de voir du code "tout fait" qu'on essaye de comprendre plutôt que de tatonner en écrivant du code qui marche mais qui est potentiellement dangereux (buggué) ou qui ne fait pas ce qu'on pense.

    Le code XSL n'étant ni très intuitif (programmation récursive + mauvaise lisibilité à cause du balisage) ni très abouti en version 1.0 (principalement à cause de XPath 1.0 qui manque de fonctionnalités), je trouve sympa de donner des exemples de code à quelqu'un qui débute, surtout quand la personne en face fait visiblement des efforts de son côté.

    Ceci dit je suis loin d'être un expert en XSL et je fais pas mal de bidouille aussi donc il est possible que mon code ne soit pas optimal, voire qu'il contienne quelques bugs...

  16. #16
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    et béni sois tu!

    Je pensais que c'etait fini mais apparemment toujours pas, donc je vais encore t’embêter... J'ai essaye avec un autre message et je me rends compte que je suis maintenant confrontee 'a deux autres problemes:

    parfois une balise peut etre 'a la fois un SEGMENT et une DATA, par exemple. mais elle garde plus ou mois la meme definition.
    Ce que j'aimerais donc faire, c'est dire "si la balise n'a pas de descendant, alors c'est une DATA" (et on garde la premiere definition que l'on a trouve, meme si elle correspondant 'a un SEGMENT)

    dans le pmier "choose" j'ai donc voulu introduire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:when test="position()=last()">   		 
    	<xsl:call-template name="opDATA">
    		<xsl:with-param name="structure" select="$structure"/>
    	</xsl:call-template>
    </xsl:when>
    'a la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:when test="$typeBalise = 'DATA'">
    (je sais que ce n'est pas tres beau mais ce projet va commencer 'a me les briser menu )

    et dans chacun des template j'ajoute la condition sur le fils (visiblement ce n'est pas ca, mais c'est dingue je n'arrive jamais 'a trouver la bonne syntaxe pour les fils) pour savoir si on a doit mettre l'entete du tableau ou non.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:when test="child::*[$structure//DATA/@SMARTNAME = local-name()] or child::[position()=last()]">

    qu'est ce qui n'est pas bon la dedans?





    j'aimerais egalement regrouper les balises qui ont le meme nom donc si j'ai
    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
    <balise0>
    	<balise1>
    		<balise2>
    			<balise3>opopop</balise3>
    			<balise3>gnagnagna</balise3>
    		</balise2>
    		<balise2>
    			<balise1>blablabla</balise1>
    			<balise5>didadidadou</balise5>
    		</balise2>
    		<balise6>
    			<balise7>
    				<balise8>pfioupioupiou</balise8>
    			</balise7>
    		</balise6>
    	</balise1>
    </balise0>
    je veux simplement mettre les "balise2" ensemble.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		<balise2>
    			<balise3>opopop</balise3>
    			<balise3>gnagnagna</balise3>
    			<balise1>blablabla</balise1>
    			<balise5>didadidadou</balise5>
    		</balise2>
    ca parait sans doute simple mais avec tous les test que je fais je n'y arrive plus, j'ai donc tente avec l'aide de la faq de mettre une cle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:key name="regrouper" match="*" use="local-name(.)"/>
    juste avant le premier template et un for-each pour regrouper les template:



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output  method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" indent="yes" />
    <xsl:key name="regrouper" match="*" use="local-name(.)"/>  
    <xsl:template match="/">
    	<html>
    	<link rel="stylesheet" type="text/css" href="style.css" />
    	<body>
     
    	<xsl:for-each select="*[generate-id(.)=generate-id(key('regrouper', .)[1])]"> 
    		<xsl:apply-templates match="*">
    			<xsl:with-param name="structure" select="document('newStruct.xml')"/>
    		</xsl:apply-templates>
    	</xsl:for-each>
    le souci c'est que, meme chose, je retourne ca dans tous les sens mais je n'ai pas le resultat attendu... et en plus il ne faut pas que ce soit le cas pour DATA (balise3) par exemple, seulement pour les balises n'ayant pas d'enfant balise disons...

    est ce que vous voyez? (je ne suis pas sure d'etre tres claire, pour le coup)

  17. #17
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Citation Envoyé par getrude Voir le message
    qu'est ce qui n'est pas bon la dedans?
    Le "position() = last()" signifie que l'élément est le dernier "frère" et non que c'est une feuille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <b1> <!-- position() = last() -->
      <b2>
        <b3/>
        <b3/> <!-- position() = last() -->
      </b2>
      <b2> <!-- position() = last() -->
        <b3/>
        <b3/> <!-- position() = last() -->
      </b2>
    </b1>
    Toi ce que tu veux c'est savoir si c'est une feuille. Pour celà, il faut tester si l'élément n'a pas de fils :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:if test="not(child::*)"><!-- ... --></xsl:if>
    Pour ton deuxième problème, c'est beaucoup plus complexe, en particulier à cause de la jointure avec l'autre fichier et avec le fait qu'un SEGMENT puisse en fait être un DATA.
    Si ce n'est pas trop gênant pour toi, je te conseille fortement de laisser tomber ce point.
    Ceci dit tu étais bien partie, il faut effectivement utiliser la méthode de Muench pour réaliser un tel traitement, mais ici je pense que ça alourdirait énormément le code pour pas grand chose.

    Ceci dit, si c'est vraiment nécéssaire j'essaierai de me pencher dessus pour t'aider.

  18. #18
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Merci beaucoup, par contre ca me fait n'importe quoi, un phenomene que je n'arrive pas 'a comprendre...
    j'ai ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
       <flightId>    <!--  segmentref  -->
        <carrierDetails>    <!--  COMPOSITEREF  -->
          <marketingCarrier>TP</marketingCarrier>    <!--  DATA  -->
        </carrierDetails>    
        <flightDetails>    <!-- SEGMENTREF and COMPOSITEREF   -->
          <flightNumber>239</flightNumber>    <!--  COMPOSITE and DATA  -->
        </flightDetails>   
        <departureDate>20111125</departureDate>    <!--  SEGMENTREF and DATA  -->
        <boardPoint>CMN</boardPoint>    <!--  DATA  -->
        <offPoint>LIS</offPoint>   <!--SEGMENTREF & DATA--> 
      </flightId>
    et ca me donne
    Nom : exforum.JPG
Affichages : 236
Taille : 73,6 Ko
    donc ca ne considere pas departureDate comme une data, et en plus ca fait un truc bizarre avec le compositeref carrierDetails (mon css fonctionne tres bien pour les autres cas)

    concernant le regroupement, en fait mes fichiers XML sont vraiment, vraiment enormes et il y a parfois 40 fois le meme segment, avec 'a l'interieur le meme composite, et seules les valeurs des DATA changent
    Le gros probleme c'est sans doute le manque d'indices pour savoir si une balise est segment, un composite ou data, parfois...

    mais je reflechis donc 'a une autre solution qui rendrait mon fichier plus lisible!

  19. #19
    Membre du Club
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2012
    Messages : 110
    Points : 65
    Points
    65
    Par défaut
    Pour le regroupement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		<xsl:when test="$typeBalise = 'SEGMENT' or $typeBalise = 'SEGMENTREF'"> 						
    			<xsl:for-each select="*[generate-id(.)=generate-id(key('regrouper', .)[1])]">	
    				<xsl:call-template name="opSEGMENT">
    					<xsl:with-param name="structure" select="$structure"/>
    				</xsl:call-template>
    			</xsl:for-each>																		
    		</xsl:when>
    pourquoi est-il si difficile de regrouper les segments?

    et donc comme j'ai dit je reflechis 'a une autre solution pour rendre le fichier plus lisible (j'aimerais quand meme combiner les 2) j'ai mis un petit truc en javascript qui permet d'afficher ou de masquer le segment (comme on voit d'ailleurs dans ma capture). c'est du javascript donc c'est pas le sujet je sais bien mais je pense que le probleme que je rencontre vient du xslt: le code ne s'applique qu'au premier element. les boutons "afficher" ou "masquer" sont sur tous les segments, mais si par exemple j'appuie sur "cacher le 3eme segment" il me cache quand meme le premier...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <div class="segment">
    	<p class="segment_smartname"><xsl:value-of select="$nomBalise"/></p>
    		<div class="segment_descr">
    			<a href="javascript:afficheId('contenu')"><xsl:value-of select="$nomBalise"/>: show content</a>
    		</div>	
    		<div class="segment" id="contenu">
    			<div class="clicCacher">
    				<a href="javascript:cacheId('contenu');">Hide content</a>
    			</div>
    			<p class="segment_description"><xsl:value-of select="$structure//*[@SMARTNAME=$nomBalise]/@DESCRIPTION"/></p>
    ceci me semble fort etrange, ca doit venir des template

  20. #20
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 843
    Points
    4 843
    Par défaut
    Là je crois qu'il va falloir que tu fournisses une version utilisable de ton code (XML corrects, XSL, CSS et Javascript).

    Pour les fichiers XML, tu peux prendre juste une sous-partie de ton XML en mettant des données bidons mais là je peux rien tester.

    Quoi qu'il en soit je crois que ça vient de ton javascript, ou plutôt de ton HTML (il nous manque la partie intéressante du HTML ou le code javascript pour savoir) : tu dois générer plusieurs fois le même ID ce qui fait que ton script javascript n'ouvre que le premier.

    Pour ce qui est du regroupement, généralement ça se fait sur des balises connues d'avance et qui ont une position fixe dans le document.
    Par exemple il est relativement simple (avec Muench) de regrouper les utilisateur par ville dans ce XML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <users>
      <user name="A">
        <location>Paris</location>
      </user>
      <user name="B">
        <location>Paris</location>
      </user>
      <user name="C">
        <location>Marseille</location>
      </user>
    </users>
    Toi dans le tient on ne sait pas :
    - quelles balises regrouper (pas de nom fixe, comportement différent selon que ce soit ou non une feuille)
    - à quel endroit elles se trouvent dans l'arborescence

    Donc déjà sans avoir le vrai XML sous les yeux c'est pas faisable (pour ma part) et je pense que même en l'ayant va falloir faire chauffer les neurones avant de trouver quelque chose de potable.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Outils sur les différences entre deux fichiers XML
    Par Community Management dans le forum XML/XSL et SOAP
    Réponses: 19
    Dernier message: 21/07/2008, 15h21
  2. [XSLT] probleme de parcourt deux fichiers xml dans xsl
    Par coucouA dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 23/07/2006, 20h32
  3. [JDOM] Comparer deux fichiers XML en Java
    Par calimero2611 dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 30/06/2006, 11h19
  4. [XML] Convertir fichier XLS en deux fichiers XML
    Par Kornoman dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 31/03/2006, 15h30
  5. Lire le contenu d'un fichier xml
    Par Invité dans le forum Bibliothèques
    Réponses: 4
    Dernier message: 10/01/2006, 19h13

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