XML > CSV - créer des copies pour chaque tuple
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:
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:
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:
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:
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="'";"'"/>
<xsl:variable name="startline" select="'"'"/>
<xsl:variable name="endline" select="'"'"/>
<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 !