I have an extremely large XSL file to transform XML into CSV. Bascially, the structure of the XML is table data. There are about 90 columns in this table (not my decision!). These columns make up a column group.
Each column group has a First and Second value, an optional Third value and a Selection which decides which value was selected in the group – this is indicated by F, S, or T – (F)irst/(S)econd/(T)hird.
The main key on the row is the Date Time column.
The XML is as follows (not this is a cut down version). So we would have up to say Column 30 for example.
<data>
<columns>
<column id="0">
<name>Date Time</name>
<type>DateTime</type>
</column>
<column id="1">
<name>Column Group 1 First</name>
<type>Double</type>
</column>
<column id="2">
<name>Column Group 1 Second</name>
<type>Double</type>
</column>
<column id="3">
<name>Column Group 1 Third</name>
<type>Double</type>
</column>
<column id="4">
<name>Column Group 1 Selection</name>
<type>String</type>
</column>
<column id="5">
<name>Column Group 2 First</name>
<type>Double</type>
</column>
<column id="6">
<name>Column Group 2 Second</name>
<type>Double</type>
</column>
<column id="7">
<name>Column Group 2 Third</name>
<type>Double</type>
</column>
<column id="8">
<name>Column Group 2 Selection</name>
<type>String</type>
</column>
<!-- This group does not have Third-->
<column id="9">
<name>Column Group 3 First</name>
<type>Double</type>
</column>
<column id="10">
<name>Column Group 3 Second</name>
<type>Double</type>
</column>
<column id="11">
<name>Column Group 3 Selection</name>
<type>String</type>
</column>
</columns>
<rows>
<row id="0">
<columns>
<column id="0">
<name>Date Time</name>
<universalDate>2010-10-10 11:30:00</universalDate>
</column>
<!-- Group 1 - - - - - - - - - - - - - - - - -->
<column id="1">
<name>Column Group 1 First</name>
<displayValue>100.123</displayValue>
<value>100.123</value>
</column>
<column id="2">
<name>Column Group 1 Second</name>
<displayValue>Missing</displayValue>
<value>-2.50E+08</value>
</column>
<column id="3">
<name>Column Group 1 Third</name>
<displayValue>Missing</displayValue>
<value>-2.50E+08</value>
</column>
<column id="4">
<name>Column Group 1 Selection</name>
<displayValue>F</displayValue>
<value>F</value>
</column>
<!-- Group 2 - - - - - - - - - - - - - - - - -->
<column id="5">
<name>Column Group 2 First</name>
<displayValue>Missing</displayValue>
<value>-2.50E+08</value>
</column>
<column id="6">
<name>Column Group 2 Second</name>
<displayValue>Missing</displayValue>
<value>-2.50E+08</value>
</column>
<column id="7">
<name>Column Group 2 Third</name>
<displayValue>93.123</displayValue>
<value>93.123</value>
</column>
<column id="8">
<name>Column Group 2 Selection</name>
<displayValue>T</displayValue>
<value>T</value>
</column>
<!-- Group 3 - - - - - - - - - - - - - - - - -->
<column id="9">
<name>Column Group 3 First</name>
<displayValue>500.3</displayValue>
<value>500.3</value>
</column>
<column id="10">
<name>Column Group 3 Second</name>
<displayValue>22.21</displayValue>
<value>22.21</value>
</column>
<column id="11">
<name>Column Group 3 Third</name>
<displayValue>S</displayValue>
<value>S</value>
</column>
</columns>
</row>
<!-- Other rows omitted -->
</rows>
</data>
The desired output would be:
Date Time,Column Group 1 Primary,Column Group 1 Secondary,Column Group 1 Third,Column Group 1 Selection
Date Time,Column Group 2 Primary,Column Group 2 Secondary,Column Group 2 Third,Column Group 2 Selection
Date Time,Column Group 3 Primary,Column Group 3 Secondary,Column Group 3 Third,Column Group 3 Selection
... and so on ...
So the output would actually be:
2010-10-10 11:30:00,100.123,,,F
2010-10-10 11:30:00,,,93.123,T
2010-10-10 11:30:00,500.3,22.21,,S
There are a couple of rules:
if the displayValue = missing then output empty string.
if the group does not have a third value then output empty string.
The first instance of my XSL is to have this check repeated for each set of columns which looks horrendous and is far too large.
The question is – is it possible to output the following XML using Templates? I have only just started working on templates (thanks to help of others in my other postings) but this has got me a little stuck.
I can link between the columns and rows to output all row column data in the table xml but this is more or less grouping 3 columns together based on the first part of the name.
My XSL for this instance looks like:
<xsl:for-each select="//rows/row">
<xsl:value-of select="columns/column[name='Date Time']/universalDate"/>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 1 First']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 1 Second']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 1 Third']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 1 Third']/rawValue,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="columns/column[name='Column 1 Selection']/value='F'">
<xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
</xsl:if>
<xsl:if test="columns/column[name='Column 1 Selection']/value='S'">
<xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
</xsl:if>
<xsl:if test="columns/column[name='Column 1 Selection']/value='T'">
<xsl:value-of select="format-number(columns/column[name='Column 1 Third']/value,'0')"/>
</xsl:if>
<!-- new line required -->
<xsl:text>
</xsl:text>
<xsl:value-of select="columns/column[name='Date Time']/universalDate"/>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 2 First']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 2 Second']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="number(columns/column[name='Column 2 Third']/value)">
<xsl:value-of select="format-number(columns/column[name='Column 2 Third']/value,'0')"/>
</xsl:if>
<xsl:text>,</xsl:text>
<xsl:if test="columns/column[name='Column 2 Selection']/value='F'">
<xsl:value-of select="format-number(columns/column[name='Column 2 First']/value,'0')"/>
</xsl:if>
<xsl:if test="columns/column[name='Column 2 Selection']/value='S'">
<xsl:value-of select="format-number(columns/column[name='Column 2 Second']/value,'0')"/>
</xsl:if>
<xsl:if test="columns/column[name='Column 2 Selection']/value='T'">
<xsl:value-of select="format-number(columns/column[name='Column 2 Third']/value,'0')"/>
</xsl:if>
<!-- new line required -->
<xsl:text>
</xsl:text>
<!-- and so on....... -->
Sorry for clarifying in the first instances.
Thanks,
Andez
This stylesheet:
Output:
Edit: Better. I was lock in previous logic, sorry.