How to inlcude a Counter in my XSL code
Hi,
I have an XSL document which displays the contents of an XML file for a list of books.
I can display the list of Books in text boxes with a check box by each book. So the user can select which books they want, then press a button at the bottom of a page to add these books to a database.
The problem I am having is naming the text boxes uniquely. At the moment each text box is named after the name of the book. However that would mean in my PHP code, I would have to hard code the names of the books, which is obviously not good.
I was hoping someone could tell me how to set up a counter so that each text box can be called; txt1, txt2, txt3 ....etc all the way to the end of the list of books.
That way in my PHP code I could just loop thru the books.
The code I am currently using is:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h3>New Books</h3>
<form action="insert.php" method="get"><input type="hidden" name="Horde" value="d9ad6cb4052a3268a73c1a0c43b4434e" />
<xsl:for-each select="//book">
<xsl:call-template name="full-details"/>
</xsl:for-each>
<input type="submit" value="Insert into db" />
</form>
</body>
</html>
</xsl:template>
<xsl:template match="book" name="full-details">
<xsl:variable name="header">
<xsl:value-of select="title" />
</xsl:variable>
<input type="text" size="40">
<xsl:attribute name = "name">
<xsl:value-of select="concat('tit',title)" />
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="title" />
</xsl:attribute>
</input>
<input type="text" size="40" >
<xsl:attribute name = "name">
<xsl:value-of select="concat('dir',title)"/>
</xsl:attribute>
<xsl:attribute name = "value">
<xsl:value-of select="director" />
</xsl:attribute>
</input>
<input type="checkbox" name="chkdvd[]">
<xsl:attribute name="value">
<xsl:value-of select="title"/>
</xsl:attribute>
</input>
<br />
</xsl:template>
</xsl:stylesheet>
Any help would be much appreciated
Regards
Gaz22
:)
[2880 byte] By [
Gaz22] at [2007-11-18 17:23:29]

# 1 Re: How to inlcude a Counter in my XSL code
In xsl, you can't declare variables (OK you can, but they can't be changed, so they are not really variables.)
What you can do is use the position() function, to get a number for each node in a node set, or you can use the id() function to get a uniqe id for any node in the source document.
You could do something like this.
<xsl:template match="/">
<html>
<body>
<h3>New Books</h3>
<form action="insert.php" method="get"><input type="hidden" name="Horde" value="d9ad6cb4052a3268a73c1a0c43b4434e" />
<xsl:apply-templates select="//book"/>
<input type="submit" value="Insert into db" />
</form>
</body>
</html>
</xsl:template>
<xsl:template match="book" name="full-details">
<xsl:variable name="position">
</xsl:value-of select="position()"/>
</xsl:variable>
<xsl:variable name="header">
<xsl:value-of select="title" />
</xsl:variable>
<input type="text" size="40">
<xsl:attribute name = "name">
<xsl:value-of select="concat('tit',title)" />
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="title" />
</xsl:attribute>
</input>
<input type="text" size="40" >
<xsl:attribute name = "name">
<xsl:value-of select="concat('dir',title)"/>
</xsl:attribute>
<xsl:attribute name = "value">
<xsl:value-of select="director" />
</xsl:attribute>
</input>
<input type="checkbox" name="chkdvd[]">
<xsl:attribute name="value">
<xsl:value-of select="title"/>
</xsl:attribute>
</input>
<br />
</xsl:template>
In the book template I have just declared the position variable, use it anywhere you like :)
Notice the change I made in the root template, I prefer not to call templates by name, unless I really really have to, and I'am not sure that the position() function would give the desired value, if the book template had been called by name.
khp at 2007-11-10 3:28:15 >

# 2 Re: How to inlcude a Counter in my XSL code
Thats great. Just to make sure I understand, does it mean that position() will be a unique number of each book?
Gaz22 at 2007-11-10 3:29:22 >

# 3 Re: How to inlcude a Counter in my XSL code
Originally posted by Gaz22
Thats great. Just to make sure I understand, does it mean that position() will be a unique number of each book?
In the code I posted above, yes it should do that.
As I said above, the position() function gives the position of the current element in relation to the nodeset it was selected to be a part of. If you changed the line.
<xsl:apply-templates select="//book"/>
to
<xsl:for-each select="//book">
<xsl:apply-templates select="."/>
</xsl:for-each>
The position function would return 1 for all book elements because each book element was selected individually.
khp at 2007-11-10 3:30:20 >

# 4 Re: How to inlcude a Counter in my XSL code
Ok, but I think I need the "for each" statement, because I am reading in several books, and each book needs a unique ID, given by the position(). so I can call the name of the text boxes and check boxes for that particular book according to its ID.
Is this still possible??
Thanks alot for your help, its much appreciated
Gaz22 at 2007-11-10 3:31:25 >

# 5 Re: How to inlcude a Counter in my XSL code
Originally posted by Gaz22
Ok, but I think I need the "for each" statement, because I am reading in several books,
No, you don't need the for-each, at least not in the code you posted.
<xsl:apply-templates select="//book"/>
Selects all the book elements in the document, and applies the best matching templates to each of them.
Originally posted by Gaz22
and each book needs a unique ID, given by the position(). so I can call the name of the text boxes and check boxes for that particular book according to its ID.
You could just use the id() function, which always produce an uniqe id for all elements in the source ducument, as I said in my first post.
Originally posted by Gaz22
Is this still possible??
If you insist on using the for-each and the position() function, you can move the position call into the for-each and pass the value into to the book template as a param.
khp at 2007-11-10 3:32:24 >
