Search code examples
xslttextibm-datapower

Transformation of text file into an xml using datapower


I want to transfer a non-xml text file delimited by '|' characters into an xml using Datapower.

Following is file  (sample1)

10|20003|24/23/25|23890

Now i have to break this into the following XML

 <ResponseType>
        <ResCode>10</ResCode>
        <Id>20003</Id>
         <SoftCode>24/23/25</SoftCode>
        <StatusCode>23890</StatusCode>
  </ResponseType>

What I did was following--

1>Create a Transform action in the service that will be receiving non-XML requests.

2>Select "Use XSLT specified in this action on a non-XML message" to specify that this is a Binary Transform.

3>Upload the following stylesheet as the Processing Control File.

    <?xml version="1.0" encoding="utf-8"?>
       <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:dp="http://www.datapower.com/extensions"
    version="1.0">

    <dp:input-mapping href="sample1.ffd" type="ffd"/>


    <xsl:output method="xml"/>

    <xsl:template match="/">
    <xsl:copy-of select="ResponseType"/>
    <xsl:call-template name="str:tokenize">
     <xsl:with-param name="string" select="string" />

    </xsl:call-template>
    </xsl:template>


    <xsl:template name="str:tokenize">
<xsl:with-param name="string" select="">

    str:tokenize('string', '|')
</xsl:with param>
</xsl:template>
    </xsl:stylesheet>

and here is my sample1.ffd(which I have uploaded in my local:// directory in Datapower

<File name="ResponseType">
<!-- capture all data into this tag -->
<Field name="ResCode/Id/SoftCode/StatusCode" />
</File> 

But I am not getting desired output , I think my xslt is quite wrong What can I do do to get desired output?


Solution

  • I'm not sure how IBM Datapower might solve this problem, but for XSLT, you would at least wrap your input in a XML element:

    <Whatever>
    10|20003|24/23/25|23890
    </Whatever> 
    

    And then you could go on with a transformation like follows. The hard part is splitting your text input. In XSLT 1.0, there is no function available for that, so you need a recursive template.

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" version="1.0" exclude-result-prefixes="msxml">
      <xsl:output method="xml" indent="yes" />
    
      <xsl:template match="/">
        <xsl:variable name="tokenized">
          <items>
            <xsl:call-template name="tokenize">
              <xsl:with-param name="string" select="//text()" />
            </xsl:call-template>
          </items>
        </xsl:variable>
        <ResponseType>
          <ResCode>
            <xsl:copy-of select="msxml:node-set($tokenized)/items/item[1]/text()" />
          </ResCode>
          <Id>
            <xsl:copy-of select="msxml:node-set($tokenized)/items/item[2]/text()" />
          </Id>
          <SoftCode>
            <xsl:copy-of select="msxml:node-set($tokenized)/items/item[3]/text()" />
          </SoftCode>
          <StatusCode>
            <xsl:copy-of select="msxml:node-set($tokenized)/items/item[4]/text()" />
          </StatusCode>
        </ResponseType>
      </xsl:template>
    
      <xsl:template name="tokenize">
        <xsl:param name="string" />
        <xsl:variable name="item" select="normalize-space( substring-before( concat( $string, '|'), '|'))" />
        <xsl:if test="$item">
          <item>
            <xsl:value-of select="$item" />
          </item>
          <xsl:call-template name="tokenize">
            <xsl:with-param name="string" select="substring-after($string,'|')" />
          </xsl:call-template>
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>