问题
I asked my entire question here on stack overflow, I'll try to chop it up:
I need to make an xml from this source: very briefly:
<?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>...
This is what I need:
<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>
This is the idea I had for the 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>
Because the lines and the headers are both contained in the E1EDL20 tag, I see the need for two templates, and both refer to the same tag in the source code. As the specs say, only the last template is being used. (so it will see 'header' and 'lines', but not 'main':
<xsl:template name="main" match="fm:ROW[1]"> ...
<xsl:template name="headers" match="fm:ROW[1]"> ...
<xsl:template name="lines" match="fm:ROW"> ...
How do I solve this?
Edit:
@Sebastien: Your solution worked great for the source code I had initially provided. Excellent answer. I made, however, a mistake in the code I provided, I apologize.
This is the format of the source code:
<?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>
The challenge is that I should have one tag with the headers, but the line items should be listed under eachother, like this:
<?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>
Thank you for bearing with me. I appreciate your help tremendously!!
Much obliged, Tom
回答1:
Here's a sample to get your started. Your question lacks some details some I assumed some rules.
<?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>
See it working here : https://xsltfiddle.liberty-development.net/6q1SDka/1
来源:https://stackoverflow.com/questions/64970677/matching-templates-with-different-configuration-on-the-same-node