Printing an invoice with XSLT
I have an XML file that I am trying to convert to XHTML using an XSLT file. I was wondering if it was possible to count the number of times the template was called. This is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" encoding="UTF-8" href="car.xslt" version="1.0"?>
<vehicle>
<car>
<make>Honda</make>
<color>blue</color>
</car>
<car>
<make>Saab</make>
<color>red</color>
</car>
</vehicle>
And this is my XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<table cellpadding="5" border="1">
<tr><td>number</td><td>make</td><td>color</td></tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="car">
<tr>
<td>#</td><td><xsl:value-of select="make"/></td><td><xsl:value-of select="color"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
I want to print the number of times the car has been printed in place #, so it will look like this:
number makes color 1 Honda blue 2 Saab red
instead:
number makes color # Honda blue # Saab red
Does anyone have any idea? I was hoping it could only be done with xsl: value-of and XPath
You can change this slightly to <xsl:apply-templates/>
do something like this instead :
<tr><td>number</td><td>make</td><td>color</td></tr>
<xsl:for-each select="/vehicle/car">
<tr>
<td><xsl:value-of select="position()" /></td><td>...</td>
</tr>
</xsl:for-each>
In this case, the function position()
will refer to the iteration number of the associated loop for-each
. This might give you what you are looking for.
source to share
Minimum change:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
>
<xsl:template match="/vehicle">
<html>
<body>
<table cellpadding="5" border="1">
<tr>
<td>number</td>
<td>make</td>
<td>color</td>
</tr>
<xsl:apply-templates select="car" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="car">
<tr>
<td><xsl:value-of select="position()" /></td>
<td><xsl:value-of select="make" /></td>
<td><xsl:value-of select="color" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Note the attribute select="car"
on <xsl:apply-templates>
. It makes sure only tags are counted <car>
, so yours is position()
not off.
Also note that the main template now matches the document element, not the root node.
source to share