I have an XML like this
<?xml version="1.0" encoding="UTF-8"?>
<Report>
<table1>
<Detail_Collection>
<Detail>
<ReceiptNo>RN12345678</ReceiptNo>
<ReceiptDate>1980/11/11</ReceiptDate>
<LastName>Dela Cruz</LastName>
<FirstName>Juan</FirstName>
<PurchaseDetails>
<Item>Wood</Item>
<Price>25.65</Price>
<Quantity>2</Quantity>
</PurchaseDetails>
<PurchaseDetails>
<Item>Axe</Item>
<Price>50.56</Price>
<Quantity>5</Quantity>
</PurchaseDetails>
</Detail>
</Detail_Collection>
</table1>
</Report>
and I need to convert it to a flat text file using XSLT 1.0
I found this nice solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" indent="no"/>
<xsl:variable name="some_spaces" select="' '" />
<xsl:template match="/">
<xsl:apply-templates select="//Detail_Collection/Detail" />
</xsl:template>
<xsl:template match="Detail_Collection/Detail">
<xsl:apply-templates mode="format" select="SSN">
<xsl:with-param name="width" select="number(9-1)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format_date" select="DOB">
<xsl:with-param name="width" select="number(17-10)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="LastName">
<xsl:with-param name="width" select="number(33-18)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="FirstName">
<xsl:with-param name="width" select="number(46-34)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format_date" select="Date">
<xsl:with-param name="width" select="number(54-47)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="Time">
<xsl:with-param name="width" select="number(62-55)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentStreetAddress1">
<xsl:with-param name="width" select="number(90-63)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentCity">
<xsl:with-param name="width" select="number(115-91)"/>
</xsl:apply-templates>
<xsl:apply-templates mode="format" select="CurrentState">
<xsl:with-param name="width" select="number(131-116)"/>
</xsl:apply-templates>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="node()" mode ="format">
<xsl:param name="width" />
<xsl:value-of select="substring(concat(text(),$some_spaces ), 1, $width+1)"/>
</xsl:template>
<xsl:template match="node()" mode="format_date">
<xsl:param name="width" />
<xsl:value-of select="substring(concat(translate(text(),'/',''),$some_spaces ), 1, $width+1)"/>
</xsl:template>
</xsl:stylesheet>
But the problem is that I have to format every detail according to its data type like below
Alphanumeric - should be 30 characters right filled with spaces
Numeric (Unsigned) - should be 15 characters left filled with zeroes e.g. 000000000012345
Numeric (signed) - should be 15 characters left filled with zeroes and if negative should denote 'N' e.g. N00000000012345
From my XML file the output should be:
RN12345678 19801111Dela Cruz Juan Wood 000000000002565000000000000002
RN12345678 19801111Dela Cruz Juan Axe 000000000005056000000000000005
and for example the prices are negative then
RN12345678 19801111Dela Cruz Juan Wood N00000000002565000000000000002
RN12345678 19801111Dela Cruz Juan Axe N00000000005056000000000000005
and by the way i have some fields that have 300 characters (like a filler) so i dont know if I need to put 300+ spaces in the variable some_spaces
Dates should be 8 characters YYYYMMDD.
I have a template which im using but not sure how to put the 'N' for the negative ones and how to format the dates according to the requirement.
Here is the template:
<xsl:template name="prepend-pad">
<!-- recursive template to right justify and prepend the value with whatever padChar is passed in -->
<xsl:param name="padChar" />
<xsl:param name="padVar" />
<xsl:param name="length" />
<xsl:choose>
<xsl:when test="string-length($padVar) < $length">
<xsl:call-template name="prepend-pad">
<xsl:with-param name="padChar" select="$padChar"/>
<xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($padVar,string-length($padVar) - $length + 1)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Thanks