I'm having input xml be like:
<row>
<entry colname="col1" colsep="0" rowsep="0">Get</entry>
<entry colname="col2" colsep="0" rowsep="0">Some</entry>
<entry colname="col3" colsep="0" rowsep="0">Manual</entry>
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0">Skip</entry>
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0" namest="col1" nameend="col3">Temp</entry>
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0" namest="col1" nameend="col3">Task</entry>
</row>
XSL I have used like below:
<xsl:template match="row">
<row>
<xsl:apply-templates/>
</row>
</xsl:template>
<xsl:template match="entry">
<entry>
<xsl:attribute name="colname">
<xsl:value-of select="@colname"/>
</xsl:attribute>
<xsl:attribute name="colsep">
<xsl:value-of select="@colsep"/>
</xsl:attribute>
<xsl:attribute name="rowsep">
<xsl:value-of select="@rowsep"/>
</xsl:attribute>
<xsl:apply-templates/>
</entry>
</xsl:template>
<xsl:template match="entry[@colname and @namest and @nameend]">
<entry>
<xsl:attribute name="colname">
<xsl:value-of select="@colname"/>
</xsl:attribute>
<xsl:attribute name="colsep">
<xsl:value-of select="@colsep"/>
</xsl:attribute>
<xsl:attribute name="rowsep">
<xsl:value-of select="@rowsep"/>
</xsl:attribute>
<xsl:attribute name="namest">
<xsl:value-of select="@namest"/>
</xsl:attribute>
<xsl:attribute name="nameend">
<xsl:value-of select="@nameend"/>
</xsl:attribute>
<xsl:apply-templates/>
</entry>
</xsl:template>
Expected output be like:
<row>
<entry colname="col1" colsep="0" rowsep="0">Get</entry>
<entry colname="col2" colsep="0" rowsep="0">Some</entry>
<entry colname="col3" colsep="0" rowsep="0">Manual</entry>
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0">Skip</entry>
<entry colname="col2" colsep="0" rowsep="0"/>
<entry colname="col3" colsep="0" rowsep="0">
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0" namest="col1" nameend="col3">Temp</entry>
</row>
<row>
<entry colname="col1" colsep="0" rowsep="0" namest="col1" nameend="col3">Task</entry>
</row>
There is having lot of entries with namest and nameend attribute. The Above entry template is working well for which having 3 entry inside the row. I want to create the new template for entry by using the count of entries inside the row. Please suggest.
Perhaps you can have a variable that stores the maximum number of entry
elements in a row
...
<xsl:variable name="cols" select="max(//row[not(entry/@namest)]/count(entry))" />
Then, have a template that matches row
elements that don't have the maximum number of entry
, and use xsl:for-each
to append new empty elements
<xsl:template match="row[not(entry[$cols])]">
<xsl:copy>
<xsl:apply-templates />
<xsl:for-each select="count(entry) + 1 to $cols">
<entry colname="col{.}" colsep="0" rowsep="0"></entry>
</xsl:for-each>
</xsl:copy>
</xsl:template>
Try this XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:variable name="cols" select="max(//row[not(entry/@namest)]/count(entry))" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="row[not(entry[$cols]) and not(entry/@namest)]">
<xsl:copy>
<xsl:apply-templates />
<xsl:for-each select="count(entry) + 1 to $cols">
<entry colname="col{.}" colsep="0" rowsep="0"></entry>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>