Modèles de correspondance avec une configuration différente sur le même nœud
J'ai posé toute ma question ici sur le débordement de pile , je vais essayer de la couper:
J'ai besoin de créer un xml à partir de cette source: très brièvement:
<?xml version="1.0" encoding="UTF-8"?>
<FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
<ROW>
<EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
<E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
<E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
<E1EDT13.1.QUALF><DATA>007<DATA></E1EDT13.1.QUALF>
<E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
<E1EDL24.POSNR>000001</E1EDL24.POSNR>
<E1EDL24.POSNR>2</E1EDL24.POSNR>
(random number of these)
<E1EDL41.QUALI>001</E1EDL41.QUALI>
<E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
<E1EDL44.POSNR>000001</E1EDL44.POSNR> <!--(these are the line items, equal to the number of ROW)-->
</ROW>
<ROW>...
C'est de quoi j'ai besoin:
<DELVRY05>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM>EDI-DC40</TABNAM>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN>649758</VBELN>
<E1EDL18 SEGMENT="1"><QUALF>ORI</QUALF></E1EDL18>
<E1EDT13 SEGMENT="1"><QUALF>007</QUALF></E1EDT13>
<E1EDT13 SEGMENT="1"><QUALF>015</QUALF></E1EDT13>
<E1EDL24 SEGMENT="1">
<POSNR>000001</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>001</QUALI>
</E1EDL41>
</E1EDL24>
<E1EDL24 SEGMENT="1">
<POSNR>2</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>001</QUALI>
</E1EDL41>
</E1EDL24>
<E1EDL24 SEGMENT="1"> <!-- (random number of these, as commented above) -->
...
</E1EDL24>
</E1EDL20>
</IDOC>
</DELVRY05>
C'est l'idée que j'ai eue pour le xsl:
<xsl:template match="/*">
<DELVRY05>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<xsl:apply-templates select="headers"/>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<xsl:apply-templates select="main"/>
<xsl:apply-templates select="fm:ROW"/>
</E1EDL20>
</IDOC>
</DELVRY05>
</xsl:template>
Étant donné que les lignes et les en-têtes sont tous deux contenus dans la balise E1EDL20, je vois la nécessité de deux modèles, et les deux font référence à la même balise dans le code source. Comme le disent les spécifications, seul le dernier modèle est utilisé. (donc il verra 'header' et 'lines', mais pas 'main':
<xsl:template name="main" match="fm:ROW[1]"> ...
<xsl:template name="headers" match="fm:ROW[1]"> ...
<xsl:template name="lines" match="fm:ROW"> ...
Comment résoudre ce problème?
Éditer:
@Sebastien: Votre solution a très bien fonctionné pour le code source que j'avais initialement fourni. Excellente réponse. J'ai cependant commis une erreur dans le code que j'ai fourni, je m'excuse.
Voici le format du code source:
<?xml version="1.0" encoding="UTF-8"?>
<FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
<ROW>
<EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
<E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
<E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
<E1EDT13.1.QUALF><DATA>007</DATA></E1EDT13.1.QUALF>
<E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
<E1EDL24.POSNR>000001</E1EDL24.POSNR>
<E1EDL41.QUALI>001</E1EDL41.QUALI>
<E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
<E1EDL44.POSNR>000001</E1EDL44.POSNR>
</ROW>
<ROW>
<EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
<E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
<E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
<E1EDT13.1.QUALF><DATA>007</DATA></E1EDT13.1.QUALF>
<E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
<E1EDL24.POSNR>2</E1EDL24.POSNR>
<E1EDL41.QUALI>002</E1EDL41.QUALI>
<E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
<E1EDL44.POSNR>000001</E1EDL44.POSNR>
</ROW>
</FMPDSORESULT>
Le défi est que je devrais avoir une balise avec les en-têtes, mais les éléments de campagne doivent être répertoriés sous l'autre, comme ceci:
<?xml version="1.0" encoding="utf-16"?>
<DELVRY05>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM>EDI_DC40</TABNAM>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN>649758</VBELN>
<E1EDL18 SEGMENT="1">
<QUALF>ORI</QUALF>
</E1EDL18>
<E1EDL24 SEGMENT="1">
<POSNR>000001</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>001</QUALI>
</E1EDL41>
</E1EDL24>
<E1EDL24 SEGMENT="1">
<POSNR>2</POSNR>
<E1EDL41 SEGMENT="1">
<QUALI>002</QUALI>
</E1EDL41>
</E1EDL24>
</E1EDL20>
</IDOC>
</DELVRY05>
Je vous remercie de m'avoir accompagné. J'apprécie énormément votre aide !!
Très obligé, Tom
Réponses
Voici un exemple pour commencer. Votre question manque de quelques détails dont j'ai supposé certaines règles.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fm="http://www.filemaker.com/fmpdsoresult"
exclude-result-prefixes="fm"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<DELVRY05>
<xsl:apply-templates select="fm:FMPDSORESULT/fm:ROW[1]"/>
</DELVRY05>
</xsl:template>
<xsl:template match="fm:ROW">
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM><xsl:value-of select="fm:EDI_DC40.TABNAM/fm:DATA"/></TABNAM>
</EDI_DC40>
<E1EDL20 SEGMENT="1">
<VBELN><xsl:value-of select="fm:E1EDL20.VBELN/fm:DATA"/></VBELN>
<E1EDL18 SEGMENT="1"><QUALF><xsl:value-of select="fm:E1EDL18.QUALF/fm:DATA"/></QUALF></E1EDL18>
<!-- Same principle as above for E1EDT13.1, E1EDT1.2, etc. -->
<!-- Use template for elements that are present mutltiple times. -->
<xsl:apply-templates select="../fm:ROW/fm:E1EDL24.POSNR"/>
</E1EDL20>
</IDOC>
</xsl:template>
<xsl:template match="fm:E1EDL24.POSNR">
<E1EDL24 SEGMENT="1">
<POSNR><xsl:value-of select="."/></POSNR>
<E1EDL41 SEGMENT="1">
<QUALI><xsl:value-of select="../fm:E1EDL41.QUALI"/></QUALI>
</E1EDL41>
</E1EDL24>
</xsl:template>
</xsl:stylesheet>
Le voir fonctionner ici: https://xsltfiddle.liberty-development.net/6q1SDka/1