Bonjour,
J'aimerai extraire et mettre en forme différentes données d'un fichier XML, le tout dans un certain ordre.
Plutôt que de prendre le risque (très probable) de rendre mon explication obscure et peu claire si je détaille plus, je préfère directement vous donner un ficher XML à titre d'exemple (avec son XSD si ça peut aider).
Le XML donc :
Code xml : 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 <Document> <Header> <Criteres> <Critere> <Flags> <Flag> <Types> <Type> <Libele>Ordre</Libele> <Valeur>2</Valeur> </Type> <Type> <Libele>Nom</Libele> <Valeur>toto</Valeur> </Type> <Type> <Libele>Type</Libele> <Valeur>int</Valeur> </Type> </Types> </Flag> <Flag> <Types> <Type> <Libele>Ordre</Libele> <Valeur>0</Valeur> </Type> <Type> <Libele>Nom</Libele> <Valeur>titi</Valeur> </Type> <Type> <Libele>Type</Libele> <Valeur>string</Valeur> </Type> </Types> </Flag> </Flags> <SousCriteres> <Critere> <Critere> <Flags> <Flag> <Types> <Type> <Libele>Ordre</Libele> <Valeur>3</Valeur> </Type> <Type> <Libele>Nom</Libele> <Valeur>tutu</Valeur> </Type> <Type> <Libele>Type</Libele> <Valeur>char</Valeur> </Type> </Types> </Flag> <Flag> <Types> <Type> <Libele>Ordre</Libele> <Valeur>1</Valeur> </Type> <Type> <Libele>Nom</Libele> <Valeur>tata</Valeur> </Type> <Type> <Libele>Type</Libele> <Valeur>double</Valeur> </Type> </Types> </Flag> </Flags> <SousCriteres /> </Critere> </Critere> </SousCriteres> </Critere> </Criteres> </Header> <Bodys> <Body> <!-- [...] --> </Body> </Bodys> <Footer> <!-- [...] --> </Footer> </Document>
le XSD :
Code xsd : 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 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Document"> <xs:complexType> <xs:sequence> <xs:element name="Header" type="ModelType" minOccurs="0" maxOccurs="1"/> <xs:element name="Bodys" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" name="Body" type="ModelType" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Footer" type="ModelType" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="ModelType"> <xs:sequence> <xs:element name="Criteres"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" name="Critere" type="CritereType" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="CritereType"> <xs:sequence> <xs:element name="Flags"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" name="Flag" type="FlagType" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="SousCriteres"> <xs:complexType> <xs:sequence > <xs:element minOccurs="0" maxOccurs="unbounded" name="Criteres" type="CritereType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="FlagType"> <xs:sequence> <xs:element name="Types"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" name="Type" type="TypeType" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="TypeType"> <xs:sequence> <xs:element name="Libele" type="xs:string" /> <xs:element name="Valeur" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:schema>
A l'issue de la transformation j'aimerai obtenir quelque chose du genre :
pour chaque flag, mais dans un ordre précis (donné par la valeur du type ayant pour libellé "Ordre").Nom (type)
Nom (type)
...
Avec le XML donné précédemment j'aimerai donc obtenir ceci :
J'ai une "solution", mais qui ne me conviens pas vraiment :titi (string)
tata (double)
toto (int)
tutu (char)
En effet ceci ne fonctionne que si tous les "ordres" sont successifs (suite atithmétique) : "0,1,2,3". Dans le cas contraire, "4,8,15,16,23,42" par exemple, ça ne fonctionne plus.
Code xslt : 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 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:call-template name="for"> <xsl:with-param name="i" select="0" /> <xsl:with-param name="max" select="3" /> <xsl:with-param name="step" select="1" /> </xsl:call-template> </xsl:template> <xsl:template name="for"> <xsl:param name="i" select="0" /> <xsl:param name="max" select="0" /> <xsl:param name="step" select="1" /> <xsl:value-of select="//Critere/Flags/Flag[Types/Type[Libele = 'Ordre']/Valeur = $i]/Types/Type[Libele = 'Nom']/Valeur"/> (<xsl:value-of select="//Critere/Flags/Flag[Types/Type[Libele = 'Ordre']/Valeur = $i]/Types/Type[Libele = 'Type']/Valeur"/>) <br/> <xsl:if test ="$i < $max"> <xsl:call-template name="for"> <xsl:with-param name="i" select="$i+$step" /> <xsl:with-param name="max" select="$max" /> <xsl:with-param name="step" select="$step" /> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet>
J'ai donc cherché du côté de <xsl:sort />, mais j'avoue que j'ai un peu de mal :
j'ai donc testé dans un premier temps ceci :
et cela :
Code xslt : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 <xsl:for-each select="//Critere"> <xsl:sort select="Flags/Flag/Types/Type[Libele = 'Ordre']/Valeur" order="ascending"/> <xsl:value-of select="." /> </xsl:for-each>
mais dans les deux cas rien n'est trié et j'ai deux fois les critères "tutu" et "tata".
Code xslt : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 <xsl:apply-templates select="//Critere"> <xsl:sort data-type="number" select="Flags/Flag/Types/Type[Libele = 'Ordre']/Valeur" order="ascending"/> </xsl:apply-templates>
C'est donc ici que je bloque, et que je fais appel à votre aide. Qu'est-ce que je fais mal / que je n'ai pas compris / que j'ai raté ?
Merci d'avance pour vos réponses.
[PS: pardonnez moi si je ne suis pas très réactif à partir de demain : je fais le pont !]
Partager