Bonjour,
Je me retrouve avec le fichier XML suivant dont je dois modifier le contenu texte de certains noeuds (nettoyer le T et Z de la date UTC, rempalcer les acronymes par des mots complets etc) :
J'ai effectué la modification des textes en créant les templates XSLT suivants :
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 <?xml version="1.0" encoding="UTF-8"?> <SyncMaterialDefinition> <ApplicationArea> <CreationDateTime>2007-09-18T18:30:00.0Z</CreationDateTime> </ApplicationArea> <DataArea> <Sync/> <MaterialDefinition> <ID>0311000</ID> <Description>Citropepsin plyn</Description> <MaterialDefinitionProperty> <ID>MaterialType</ID> <Value> <ValueString>SFP</ValueString> <DataType>ID</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BaseUnitOfMeasure</ID> <Value> <ValueString>KG</ValueString> <DataType>NOTATION</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BatchManagement</ID> <Value> <ValueString>1</ValueString> <DataType>boolean</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TotalShelfLive</ID> <Value> <ValueString>60</ValueString> <DataType>integer</DataType> <UnitOfMeasure>Days</UnitOfMeasure> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TimeStamp</ID> <Value> <ValueString>2004-08-21T14:00:00.0Z</ValueString> <DataType>dateTime</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> </MaterialDefinition> <MaterialDefinition> <ID>1341750001</ID> <Description>Pepsyna</Description> <MaterialDefinitionProperty> <ID>MaterialType</ID> <Value> <ValueString>RM</ValueString> <DataType>ID</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BaseUnitOfMeasure</ID> <Value> <ValueString>KG</ValueString> <DataType>NOTATION</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BatchManagement</ID> <Value> <ValueString>1</ValueString> <DataType>boolean</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TotalShelfLive</ID> <Value> <ValueString>200</ValueString> <DataType>integer</DataType> <UnitOfMeasure>Days</UnitOfMeasure> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TimeStamp</ID> <Value> <ValueString>2003-12-03T12:37:57.0Z</ValueString> <DataType>dateTime</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> </MaterialDefinition> <MaterialDefinition> <ID>1331420004</ID> <Description>Kwas cytrynowy</Description> <MaterialDefinitionProperty> <ID>MaterialType</ID> <Value> <ValueString>RM</ValueString> <DataType>ID</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BaseUnitOfMeasure</ID> <Value> <ValueString>G</ValueString> <DataType>NOTATION</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>KgPerUnit</ID> <Value> <ValueString>0.001</ValueString> <DataType>decimal</DataType> <UnitOfMeasure>KG</UnitOfMeasure> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BatchManagement</ID> <Value> <ValueString>1</ValueString> <DataType>boolean</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TotalShelfLive</ID> <Value> <ValueString>150</ValueString> <DataType>integer</DataType> <UnitOfMeasure>Days</UnitOfMeasure> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TimeStamp</ID> <Value> <ValueString>2001-02-12T08:25:56.0Z</ValueString> <DataType>dateTime</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> </MaterialDefinition> <MaterialDefinition> <ID>1331730001</ID> <Description>Fosforan 1-zasad. sodowy x2H2O</Description> <MaterialDefinitionProperty> <ID>MaterialType</ID> <Value> <ValueString>RM</ValueString> <DataType>ID</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BaseUnitOfMeasure</ID> <Value> <ValueString>KG</ValueString> <DataType>NOTATION</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>BatchManagement</ID> <Value> <ValueString>1</ValueString> <DataType>boolean</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TotalShelfLive</ID> <Value> <ValueString>200</ValueString> <DataType>integer</DataType> <UnitOfMeasure>Days</UnitOfMeasure> </Value> </MaterialDefinitionProperty> <MaterialDefinitionProperty> <ID>TimeStamp</ID> <Value> <ValueString>2001-02-12T08:25:56.0Z</ValueString> <DataType>dateTime</DataType> <UnitOfMeasure/> </Value> </MaterialDefinitionProperty> </MaterialDefinition> </DataArea> </SyncMaterialDefinition>
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 <!-- BEGIN Templates --> <xsl:template match="/"> <xsl:apply-templates select="//UnitOfMeasure"/> </xsl:template> <xsl:template match="/SyncMaterialDefinition" > <xsl:for-each select="DataArea/MaterialDefinition/MaterialDefinitionProperty"> <xsl:if test="ID = 'TimeStamp' "> <xsl:value-of select="concat(substring(Value/ValueString,1,10), ' ', substring(Value/ValueString,12,8) )" /> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="/SyncMaterialDefinition/ApplicationArea"> <xsl:value-of select="concat(substring(CreationDateTime,1,10), ' ', substring(CreationDateTime,12,8) )"/> </xsl:template> <xsl:template match="/SyncMaterialDefinition/DataArea/MaterialDefinition"> <xsl:for-each select="MaterialDefinitionProperty"> <xsl:if test="ID = 'MaterialType' "> <xsl:choose> <xsl:when test=" Value/ValueString = 'RM' " > <xsl:value-of select=" 'Raw material' " /> </xsl:when> <xsl:when test=" Value/ValueString = 'PI' "> <xsl:value-of select=" 'Packaging articles' " /> </xsl:when> <xsl:when test=" Value/ValueString = 'SFP' "> <xsl:value-of select=" 'Semi Finished Product' " /> </xsl:when> <xsl:when test=" Value/ValueString = 'FP' "> <xsl:value-of select=" 'Finished Product' " /> </xsl:when> <xsl:when test=" Value/ValueString = 'CONT' "> <xsl:value-of select=" 'Container' " /> </xsl:when> </xsl:choose> </xsl:if> <!-- Converts units of mesure --> <xsl:if test="ID = 'BaseUnitOfMeasure' "> <xsl:choose> <xsl:when test="Value/ValueString = 'G' "> <xsl:value-of select="Grams" /> </xsl:when> <xsl:when test="Value/ValueString = 'KG' "> <xsl:value-of select=" 'Kilograms' " /> </xsl:when> </xsl:choose> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <!-- END Templates -->
J'ai bien trouvé comment reproduire tout un XML en appelant ce template depuis le noeud racine :
Mais ce qui me pose problème, c'est de recracher un XML reproduisant le document XML de départ, AVEC les champs textes transformés par les templates ci-dessus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template>
Transformer les textes via XSLT est fait. Reproduire l'intégralité du texte XML source est ok. Mais faire les deux à la fois : aïe aïe aïe. Je me retrouve souvent avec des <xsl:for-each> imbriqués aboutissant à ... des stack overflow, sans doute causés par des boucles infinies.
En résumé, (je crois que) j'ai un problème d'application de mes templates.
Merci d'avance
PS : J'ai appris XSLT sur le tas et ai cherché une équivalence avec des choses que je connaissais d'autres langages (quand j'avais besoin d'un "switch case", j'ai cherché un équivalent XSLT et suis tombé "xsl:choose" par exemple), donc je n'ai sûrement pas une façon de faire orthodoxe en XSLT et prie les puristes du XSLT et XPath de pardonner l'utilisation étrange que j'ai dû faire de ces langages. Idem avec le recours a substring() et concat() pour reformater mes dates ...
Partager