Reputation: 67
I have an xml on which I am applying xsl to transform into pipe delimited file. I am able to get the output but I also need a record count at the end of file. Please help.
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="delimeter" select="'|'"/>
<xsl:variable name="lineFeed" select="'
'"/>
<xsl:text>Headers</xsl:text>
<xsl:value-of select="$lineFeed"/>
<!--<xsl:for-each select="wd:Report_Data/wd:Report_Entry">-->
<xsl:for-each-group select="wd:Report_Data/wd:Report_Entry" group-by="wd:Worker_group/wd:Employee_ID">
<!-- HDRCOM - Print Company Details -->
<text>HDRCOM</text>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Worker_group/wd:Company_Name"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Worker_group/wd:Company_Address"/>
<xsl:value-of select="$lineFeed"/>
<!-- HDRBIO (Employee Information) -->
<text>HDRBIO</text>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Worker_group/wd:Full_Legal_Name"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Worker_group/wd:Employee_ID"/>
<xsl:value-of select="$delimeter"/>
<!-- TAXES (Repeat the seqment for each type of Tax) -->
<xsl:for-each select="current-group()">
<xsl:choose>
<xsl:when test="wd:Pay_Component_Category = 'Employee Paid Taxes'">
<text>TAXES</text>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Pay_Component"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:Amount"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="wd:YTD_Amount"/>
<xsl:value-of select="$lineFeed"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!--</xsl:for-each>-->
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
My output looks like:
HDRCOM|ABC|XYZ
HDRBIO|Andrew|12345
TAXES|Fed Withholdng A| 0.00| 0.00
TAXES|Fed Withholdng B| 1.95| 4.40
TAXES|Fed Withholdng C| 8.37| 18.83
HDRCOM|ABC|XYZ
HDRBIO|John|16543
TAXES|Fed Withholdng A| 1.00| 1.00
TAXES|Fed Withholdng B| 2.65| 4.40
TLR| 09 -----> I need this. TOTAL NUMBER OF LINES PRINTED.
Input:
<?xml version='1.0' encoding='UTF-8'?>
<wd:Report_Data xmlns:wd="urn:com.workday/bsvc">
<wd:Report_Entry>
<wd:Worker_group>
<wd:Company_Name>ABC</wd:Company_Name>
<wd:Company_Address>XYZ</wd:Company_Address>
<wd:Full_Legal_Name>Andrew</wd:Full_Legal_Name>
<wd:Employee_ID>12345</wd:Employee_ID>
</wd:Worker_group>
<wd:Pay_Component>Fed Withholdng A</wd:Pay_Component>
<wd:Amount>0</wd:Amount>
<wd:YTD_Amount>0</wd:YTD_Amount>
<wd:Pay_Component_Category>Employee Paid Taxes</wd:Pay_Component_Category>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Company_Name>ABC</wd:Company_Name>
<wd:Company_Address>XYZ</wd:Company_Address>
<wd:Full_Legal_Name>Andrew</wd:Full_Legal_Name>
<wd:Employee_ID>12345</wd:Employee_ID>
</wd:Worker_group>
<wd:Pay_Component>Fed Withholdng B</wd:Pay_Component>
<wd:Amount>1.95</wd:Amount>
<wd:YTD_Amount>4.40</wd:YTD_Amount>
<wd:Pay_Component_Category>Employee Paid Taxes</wd:Pay_Component_Category>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Company_Name>ABC</wd:Company_Name>
<wd:Company_Address>XYZ</wd:Company_Address>
<wd:Full_Legal_Name>Andrew</wd:Full_Legal_Name>
<wd:Employee_ID>12345</wd:Employee_ID>
</wd:Worker_group>
<wd:Pay_Component>Fed Withholdng C</wd:Pay_Component>
<wd:Amount>8.37</wd:Amount>
<wd:YTD_Amount>18.83</wd:YTD_Amount>
<wd:Pay_Component_Category>Employee Paid Taxes</wd:Pay_Component_Category>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Company_Name>ABC</wd:Company_Name>
<wd:Company_Address>XYZ</wd:Company_Address>
<wd:Full_Legal_Name>John</wd:Full_Legal_Name>
<wd:Employee_ID>16543</wd:Employee_ID>
</wd:Worker_group>
<wd:Pay_Component>Fed Withholdng A</wd:Pay_Component>
<wd:Amount>1</wd:Amount>
<wd:YTD_Amount>1</wd:YTD_Amount>
<wd:Pay_Component_Category>Employee Paid Taxes</wd:Pay_Component_Category>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_group>
<wd:Company_Name>ABC</wd:Company_Name>
<wd:Company_Address>XYZ</wd:Company_Address>
<wd:Full_Legal_Name>John</wd:Full_Legal_Name>
<wd:Employee_ID>16543</wd:Employee_ID>
</wd:Worker_group>
<wd:Pay_Component>Fed Withholdng B</wd:Pay_Component>
<wd:Amount>2.65</wd:Amount>
<wd:YTD_Amount>4.40</wd:YTD_Amount>
<wd:Pay_Component_Category>Employee Paid Taxes</wd:Pay_Component_Category>
</wd:Report_Entry>
</wd:Report_Data>
Upvotes: 0
Views: 122
Reputation: 116982
I'd suggest you try it this way:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="urn:com.workday/bsvc">
<xsl:output method="text"/>
<xsl:template match="/Report_Data">
<xsl:variable name="items" select="Report_Entry[Pay_Component_Category = 'Employee Paid Taxes']" />
<xsl:for-each-group select="$items" group-by="Worker_group/Employee_ID">
<!-- HDRCOM - Print Company Details -->
<xsl:value-of select="'HDRCOM', Worker_group/Company_Name, Worker_group/Company_Address" separator="|"/>
<xsl:text> </xsl:text>
<!-- HDRBIO (Employee Information) -->
<xsl:value-of select="'HDRBIO', Worker_group/Full_Legal_Name, Worker_group/Employee_ID" separator="|"/>
<xsl:text> </xsl:text>
<!-- TAXES (Repeat the seqment for each type of Tax) -->
<xsl:for-each select="current-group()">
<xsl:value-of select="'TAXES', Pay_Component, Amount, YTD_Amount" separator="|"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
<!-- count lines -->
<xsl:value-of select="'TLR', count($items) + 2*count(distinct-values($items/Worker_group/Employee_ID))" separator="|"/>
</xsl:template>
</xsl:stylesheet>
Note that there is a difference between my logic and yours: my method will not create headers for an empty group.
Upvotes: 1
Reputation: 3215
A simple way would be to capture the textual record which you're generating as a string variable and then count the number of occurrences of line feed characters it contains.
<xsl:variable name="record">
<!-- insert your record-generation code here -->
</xsl:variable>
<!-- output the body of the record -->
<xsl:sequence select="$record"/>
<!-- compute the line count -->
<xsl:variable name="lines" select="count(tokenize($record, '\n')) + 1"/>
<!-- finally output the $lines information -->
You can use the format-number()
function to format the line count with a leading zero if that's what you need. https://www.w3.org/TR/xslt20/#function-format-number
Upvotes: 1