am new in xslt and I am creating a PDF from an xml code using xslt 1.0.
My source data is the below one.
<STATEMENT>
<STATEMENT_AGING>
<AGING>
<AGING_LABEL>Current</AGING_LABEL>
<AGING_AMOUNT>$28,927.43</AGING_AMOUNT>
</AGING>
<AGING>
<AGING_LABEL>1 - 30</AGING_LABEL>
<AGING_AMOUNT>$0.00</AGING_AMOUNT>
</AGING>
<AGING>
<AGING_LABEL>31 - 60</AGING_LABEL>
<AGING_AMOUNT>$0.00</AGING_AMOUNT>
</AGING>
<AGING>
<AGING_LABEL>61 - 90</AGING_LABEL>
<AGING_AMOUNT>$0.00</AGING_AMOUNT>
</AGING>
<AGING>
<AGING_LABEL>91 - 120</AGING_LABEL>
<AGING_AMOUNT>$0.00</AGING_AMOUNT>
</AGING>
<AGING>
<AGING_LABEL>Over 120</AGING_LABEL>
<AGING_AMOUNT>$0.00</AGING_AMOUNT>
</AGING>
</STATEMENT_AGING>
<GROUP
ID='1'
label=''>
<GROUP_LABEL />
<GROUP_NAME>SoleraStatementSection</GROUP_NAME>
<GROUP_TYPE>LABEL</GROUP_TYPE>
<GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
<GROUP_HEADER_ROW>
<COL
headerAlign='start'
headerFormat='text'
width='2cm'>Doc. #</COL>
<COL
headerAlign='start'
headerFormat='text'
width='1cm'>Doc. Type</COL>
<COL
headerAlign='start'
headerFormat='text'
width='1cm'>Doc. Date</COL>
<COL
headerAlign='start'
headerFormat='text'
width='1cm'>Due Date</COL>
<COL
headerAlign='center'
headerFormat='text'
width='1cm'>Currency</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='1cm'>Original Amount</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='1cm'>Balance</COL>
<COL
headerAlign='start'
headerFormat='number'
width='1cm'>ChildAccount</COL>
</GROUP_HEADER_ROW>
<GROUP_DATA_ROW>
<COL>2120-000023134</COL>
<COL>Invoice</COL>
<COL>2024-05-13T00:23:14.205918-05:00</COL>
<COL>2024-06-12T05:00:00.000000+00:00</COL>
<COL>USD</COL>
<COL>$13,247.46</COL>
<COL>$13,247.46</COL>
<COL>Price Acura</COL>
</GROUP_DATA_ROW>
<GROUP_DATA_ROW>
<COL>2120-000023135</COL>
<COL>Invoice</COL>
<COL>2024-05-13T00:36:37.008144-05:00</COL>
<COL>2024-06-12T05:00:00.000000+00:00</COL>
<COL>USD</COL>
<COL>$13,247.37</COL>
<COL>$13,247.37</COL>
<COL>Price Acura</COL>
</GROUP_DATA_ROW>
<GROUP_DATA_ROW>
<COL>2120-000023136</COL>
<COL>Invoice</COL>
<COL>2024-05-13T00:51:32.838201-05:00</COL>
<COL>2024-06-12T05:00:00.000000+00:00</COL>
<COL>USD</COL>
<COL>$2,432.60</COL>
<COL>$2,432.60</COL>
<COL>Price Honda</COL>
</GROUP_DATA_ROW>
</GROUP>
<GROUP ID='2'
label=''>
<GROUP_LABEL />
<GROUP_NAME>CreditData</GROUP_NAME>
<GROUP_TYPE>LABEL</GROUP_TYPE>
<GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
<GROUP_HEADER_ROW>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Credit #</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Credit Type</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Credit Date</COL>
<COL
headerAlign='center'
headerFormat='text'
width='0cm'>Currency</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='0cm'>Credit Amount</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='0cm'>Unallocated Amnt</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>ChildAccount</COL>
</GROUP_HEADER_ROW>
</GROUP>
<GROUP ID='3'
label=''>
<GROUP_LABEL />
<GROUP_NAME>PaymentSection</GROUP_NAME>
<GROUP_TYPE>LABEL</GROUP_TYPE>
<GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
<GROUP_HEADER_ROW>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Payment #</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Payment Type</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>Payment Date</COL>
<COL
headerAlign='center'
headerFormat='text'
width='0cm'>Currency</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='0cm'>Payment Amount</COL>
<COL
headerAlign='end'
headerFormat='currency'
width='0cm'>Unallocated Amnt</COL>
<COL
headerAlign='start'
headerFormat='text'
width='0cm'>ChildAccount</COL>
</GROUP_HEADER_ROW>
</GROUP>
</STATEMENT>
The thing is that in the GROUPID 1 I’m trying to group the data by custName or col[8] but I want to print the header everytime this custName change. I tried to store the value into an variable but once the loop comes up again, the value is lost, so my IF am trying to use to evalute is not working.
Does anyone has an idea of how can I manage this, because I saw a lot of answers with diff methods but I don’t understand quite well all of them because my source xml has “generic” labels intead of real label names.
PS. I tried with a choose and if condition but none of them are working.
<xsl:template name= "DetailSectionG1">
<fo:block space-before="8mm" font-weight="bold" color="{$blue-color}" keep-together.within-page="always" keep-with-next="always">
<fo:table width="100%" border-collapse="collapse" table-layout="fixed">
<fo:table-column column-width="{$left-margin}"/>
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-column column-width="{$right-margin}"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
<fo:table-cell>
<fo:block font-size="{$large-font-size}" padding-top="3 * {$padding}" padding-bottom="{$padding}">
Statement Details
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
<xsl:choose>
<xsl:when test="GROUP[@ID=1]/GROUP_DATA_ROW/COL[1] !=''">
<fo:block>
<fo:table width="100%" border-collapse="collapse" table-layout="fixed">
<fo:table-column column-width="{$data-left-margin}"/>
<fo:table-column column-width="30mm"/>
<fo:table-column column-width="25mm"/>
<fo:table-column column-width="25mm"/>
<fo:table-column column-width="25mm"/>
<fo:table-column column-width="22mm"/>
<fo:table-column column-width="27mm"/>
<fo:table-column column-width="25mm"/>
<fo:table-column column-width="{$data-right-margin}"/>
<xsl:for-each select="/STATEMENT/GROUP[@ID=1]/GROUP_DATA_ROW[generate-id(.)=generate-id(key('groupDataRow', concat(COL[position() = 8],'+',COL[position() = 1])))]">
<xsl:variable name="vGroup" select="key('kAllFields', concat(COL[position() = 8],'+',COL[position() = 1]))"/>
<fo:table-body>
<xsl:choose>
<xsl:when test="custName != COL[position() = 8] or position() = 1">
<fo:table-row>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
<fo:table-cell>
<fo:block font-weight="bold" color="{$blue-color}" keep-together.within-page="always" keep-with-next="always" padding-bottom="{$padding}"/>
<!--xsl:value-of select="COL[position() = 8]"/-->
<!--/fo:block-->
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">1</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">2</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">3</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">4</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">5</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">6</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
<xsl:call-template name="HeaderCell">
<xsl:with-param name="position">7</xsl:with-param>
<xsl:with-param name="color" select="$blue-color"/>
</xsl:call-template>
</fo:table-row>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
<!--xsl:if test="{$acctName} != COL[position() = 8] or position() = 1"> </xsl:if-->
<fo:table-row>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
<xsl:call-template name="Cell">
<xsl:with-param name="position">1</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="Cell">
<xsl:with-param name="position">2</xsl:with-param>
</xsl:call-template>
<fo:table-cell>
<fo:block color="{$base-color}" padding-bottom="{$small-padding}">
<xsl:attribute name="end-indent">1mm</xsl:attribute>
<xsl:attribute name="text-align">
<xsl:value-of select="../GROUP_HEADER_ROW[1]/COL[position() = 3]/@headerAlign"/>
</xsl:attribute>
<xsl:call-template name="getDate">
<xsl:with-param name="value" select="COL[position()=3]"/>
</xsl:call-template>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block color="{$base-color}" padding-bottom="{$small-padding}">
<xsl:attribute name="end-indent">1mm</xsl:attribute>
<xsl:attribute name="text-align">
<xsl:value-of select="../GROUP_HEADER_ROW[1]/COL[position() = 4]/@headerAlign"/>
</xsl:attribute>
<xsl:call-template name="getDate">
<xsl:with-param name="value" select="COL[position()=4]"/>
</xsl:call-template>
</fo:block>
</fo:table-cell>
<xsl:call-template name="Cell">
<xsl:with-param name="position">5</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="Cell">
<xsl:with-param name="position">6</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="Cell">
<xsl:with-param name="position">7</xsl:with-param>
</xsl:call-template>
</fo:table-row>
<xsl:variable name="custName">
<xsl:value-of select="COL[position() = 8]"/>
</xsl:variable>
</fo:table-body>
</xsl:for-each>
</fo:table>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block keep-together.within-page="always" keep-with-next="always">
<fo:table width="100%" border-collapse="collapse" table-layout="fixed">
<fo:table-column column-width="{$left-margin}"/>
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-column column-width="{$right-margin}"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
<fo:table-cell>
<fo:block color="{$base-color}" padding-bottom="{$small-padding}" end-indent="1mm">
No invoices to display
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
My PDF expectation is this one.
[Expectation Output] (https://i.sstatic.net/GPAPwxHQ.png)
For now the validation I am trying is not working and the acctName and header table is showing only once.
Current Output
Javier Bosque is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.