Mapowanie XSLT do pliku płaskiego

W niektórych sytuacjach wymagane jest przesłanie pliku wynikowego jako płaskiego o określonej długości każdego pola. W przypadku adaptera plikowego można z powodzeniem skorzystać z File Content Conversion, jednak w przypadku na przykład wywołania usługi sieciowej najlepszym rozwiązaniem będzie przekształcenie XSLT. Dla przykładowego pliku wejściowego:

[codesyntax lang=”xml” lines=”normal”]

<Order>
   <Header>
      <DocumentNumber>001</DocumentNumber>
      <Date>20140401</Date>
   </Header>
   <Line>
      <ItemNumber>1</ItemNumber>
      <Material>1203040</Material>
      <Quantity>10</Quantity>
      <UOM>PCE</UOM>
   </Line>
   <Line>
      <ItemNumber>2</ItemNumber>
      <Material>2349040</Material>
      <Quantity>20</Quantity>
      <UOM>PCE</UOM>
   </Line>
</Order>

[/codesyntax]

Po zastosowaniu transformacji tworzącej nową linię dla każdego powtórzenia elementu <Line> i ustawiającej długości każdego pola na odpowiednio 20, 20, 3, 20, 5, 5:
[codesyntax lang=”xml” lines=”normal”]

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="text" indent="yes" encoding="UTF-8" />
   <xsl:variable name="DocumentNumber">
      <xsl:call-template name="padRightSide">
         <xsl:with-param name="stringToPad" select="Order/Header/DocumentNumber" />
         <xsl:with-param name="totalLength" select="20" />
      </xsl:call-template>
   </xsl:variable>
   <xsl:variable name="Date">
      <xsl:call-template name="padRightSide">
         <xsl:with-param name="stringToPad" select="Order/Header/Date" />
         <xsl:with-param name="totalLength" select="20" />
      </xsl:call-template>
   </xsl:variable>
   <xsl:template match="/Order">
      <xsl:for-each select="Line">
         <!-- Repeat header data -->
         <xsl:copy-of select="$DocumentNumber" />
         <xsl:copy-of select="$Date" />
         <!-- Item data -->
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="ItemNumber" />
            <xsl:with-param name="totalLength" select="3" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="Material" />
            <xsl:with-param name="totalLength" select="20" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="Quantity" />
            <xsl:with-param name="totalLength" select="5" />
         </xsl:call-template>
         <xsl:call-template name="padRightSide">
            <xsl:with-param name="stringToPad" select="UOM" />
            <xsl:with-param name="totalLength" select="5" />
         </xsl:call-template>
         <!-- End Line -->
         <xsl:text />
      </xsl:for-each>
   </xsl:template>
   <xsl:template name="padRightSide">
      <xsl:param name="totalLength" />
      <xsl:param name="padChar" select="' '" />
      <xsl:param name="stringToPad" />
      <xsl:param name="padBuffer" select="concat($padChar,$padChar,$padChar,$padChar,$padChar, $padChar,$padChar,$padChar,$padChar,$padChar )" />
      <xsl:variable name="vNewString" select="concat($stringToPad, $padBuffer)" />
      <xsl:choose>
         <xsl:when test="not(string-length($vNewString) &gt;= $totalLength)">
            <xsl:call-template name="padRightSide">
               <xsl:with-param name="stringToPad" select="$vNewString" />
               <xsl:with-param name="totalLength" select="$totalLength" />
               <xsl:with-param name="padChar" select="$padChar" />
               <xsl:with-param name="padBuffer" select="$padBuffer" />
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:variable name="output">
               <xsl:value-of disable-output-escaping="no" select="substring($vNewString,1,$totalLength)" />
            </xsl:variable>
            <xsl:value-of select="$output" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

[/codesyntax]

otrzymujemy:
001 20140401 1 1203040 10 PCE
001 20140401 2 2349040 20 PCE