Bonjour,

Je dois transformer un fichier XML ayant plusieurs noeuds du même niveaux, en CSV.
Les différents noeuds-frères sont liés entre eux par des clés multiples.

Mon problème : je n'arrive pas à comprendre comment utiliser <xsl:copy> ou <xsl:copy-of> pour obtenir le résultat attendu : une duplication des parties pour obtenir 1 ligne par tuple.

Mon 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
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
<?xml version='1.0' encoding='ISO-8859-1'?>
<EXPORT>
	<PART_1>
		<FORFAIT>
			<NAME>
				<![CDATA[Item n°1]]>
			</NAME>
			<CODE>114</CODE>
			<PART_CODE>201</PART_CODE>
			<ENGINE>
				<![CDATA[A]]>
			</ENGINE>
			<LABOUR_CODE>231044009</LABOUR_CODE>
		</FORFAIT>
		<FORFAIT>
			<NAME>
				<![CDATA[Item n°2]]>
			</NAME>
			<CODE>115</CODE>
			<PART_CODE>202</PART_CODE>
			<ENGINE>
				<![CDATA[B]]>
			</ENGINE>
			<LABOUR_CODE>4554003330</LABOUR_CODE>
		</FORFAIT>
		<FORFAIT>
			<NAME>
				<![CDATA[Item n°3]]>
			</NAME>
			<CODE>116</CODE>
			<PART_CODE>203</PART_CODE>
			<ENGINE>
				<![CDATA[C]]>
			</ENGINE>
			<LABOUR_CODE>8794312220</LABOUR_CODE>
		</FORFAIT>
	</PART_1>
	<PART_2>
		<SPARE_PART>
			<PART_CODE>201</PART_CODE>
			<ENGINE>
				<![CDATA[A]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 201 A]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>328.60</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>201</PART_CODE>
			<ENGINE>
				<![CDATA[A]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 201 A blabla]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>66.05</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>202</PART_CODE>
			<ENGINE>
				<![CDATA[A]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 202 A]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>38.10</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>202</PART_CODE>
			<ENGINE>
				<![CDATA[B]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 202 B blabla]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>563.00</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>203</PART_CODE>
			<ENGINE>
				<![CDATA[C]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 203 C blabla]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>4.50</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>203</PART_CODE>
			<ENGINE>
				<![CDATA[C]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 203 C nouveau texte]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>4.40</PART_SALE_PRICE>
		</SPARE_PART>
		<SPARE_PART>
			<PART_CODE>203</PART_CODE>
			<ENGINE>
				<![CDATA[C]]>
			</ENGINE>
			<PART_NAME>
				<![CDATA[Descriptif 203 C dernier texte]]>
			</PART_NAME>
			<PART_QUANTITY>1.00</PART_QUANTITY>
			<PART_SALE_PRICE>2.00</PART_SALE_PRICE>
		</SPARE_PART>
	</PART_2>
</EXPORT>
Le résultat attendu :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
NAME;CODE;PART_CODE;ENGINE;LABOUR_CODE;PART_NAME;PART_QUANTITY;PART_SALE_PRICE
Item n°1;114;201;A;231044009;Descriptif 201 A;1.00;328.60
Item n°1;114;201;A;231044009;Descriptif 201 A blabla;1.00;66.05
Item n°2;115;202;B;4554003330;Descriptif 202 B blabla;1.00;563.00
Item n°3;116;203;C;8794312220;Descriptif 203 C blabla;1.00;4.50
Item n°3;116;203;C;8794312220;Descriptif 203 C nouveau texte;1.00;4.40
Item n°3;116;203;C;8794312220;Descriptif 203 C dernier texte;1.00;2.00
Je parviens à ce résultat pour l'instant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
NAME;CODE;PART_CODE;ENGINE;LABOUR_CODE;PART_NAME;PART_QUANTITY;PART_SALE_PRICE
Item n°1;114;201;A;231044009
Item n°2;115;202;B;4554003330
Item n°3;116;203;C;8794312220
Avec ce XSLT :
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
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:csv="csv:csv">
 
 
	<xsl:variable name="delimiter" select="'&quot;;&quot;'"/>
	<xsl:variable name="startline" select="'&quot;'"/>
	<xsl:variable name="endline" select="'&quot;'"/>
 
 
	<csv:columns>
		<!-- PART_1 -->
		<column>NAME</column>
		<column>CODE</column>
		<column>PART_CODE</column>
		<column>ENGINE</column>
		<column>LABOUR_CODE</column>
		<!-- PART_2 -->
		<column>PART_NAME</column>
		<column>PART_QUANTITY</column>
		<column>PART_SALE_PRICE</column>
	</csv:columns>
 
	<xsl:template match="/">
		<!-- Output the CSV header -->
		<xsl:for-each select="document('')/*/csv:columns/*">
			<xsl:value-of select="."/>
			<xsl:if test="position() != last()">
				<xsl:value-of select="$delimiter"/>
			</xsl:if>
		</xsl:for-each>
		<xsl:text>
		</xsl:text>
		<!-- Output rows for each matched property -->
		<xsl:apply-templates select="//FORFAIT" />
	</xsl:template>
 
	<xsl:template match="FORFAIT">
		<xsl:copy>
 
			<xsl:value-of select="$startline" />
 
			<xsl:variable name="current_op_part_code" select ="$forfait/*[name()='OPERATION_PART_CODE']" />
 
			<!-- NAME -->
			<xsl:value-of select="NAME" />
			<xsl:value-of select="$delimiter"/>
 
			<!-- CODE -->
			<xsl:value-of select="CODE" />
			<xsl:value-of select="$delimiter"/>
 
			<!-- PART_CODE -->
			<xsl:value-of select="PART_CODE" />
			<xsl:value-of select="$delimiter"/>
 
			<!-- ENGINE -->
			<xsl:value-of select="ENGINE" />
			<xsl:value-of select="$delimiter"/>
 
			<!-- LABOUR_CODE -->
			<xsl:value-of select="LABOUR_CODE" />
			<xsl:value-of select="$delimiter"/>
 
 
		</xsl:copy>
 
		<xsl:value-of select="$endline" />
 
		<xsl:text>
		</xsl:text>
	</xsl:template>
Précisions :
- Il faut partir de <Part_1> et boucler sur <part_2> pour obtenir autant de <PART_CODE> et <ENGINE> qui correspondent...
- Je sais que le XSL peut être factorisé mais pour l'instant j'avance à tâtons...
- J'ai largement édulcoré le fichier en entrée et le résultat obtenu ... pour ne vous exposer que le problème rencontré

Merci pour votre aide !