View Full Version : Creating a Counter : Help
TheJoey
04-20-2010, 06:36 AM
Hey guys, trying to create a counter that relies on another xml element and then simply counts it, im trying to do this in a for-each loop but not sure how to do it, open to doing it another way also.
<xml>
<bookoptions1>
<book> abc </book>
<book>abccc </book>
<book> hghghg </book>
<ammountofbooks> ??????? </ammountofbooks> (want this to count the ammount of book elements)
</bookoptions1>
<xml>
was thinking something like this
<xsl:for-each>
<ammountofbooks>
<xsl:value-of select="count(books)"/>
</ammountofbooks>
</xsl:for-each>
but dont think this will work effiectlly as it will just keep adding..
Dormilich
04-20-2010, 08:38 AM
your call to <xsl:for-each> is invalid.
TheJoey
04-20-2010, 08:43 AM
How so?
i get it to produce a counter element for each book, but that is were the problem lies
if there is in this case 4 books i want ammountofbooks to be 4
instead of
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
Dormilich
04-20-2010, 10:06 AM
instead of
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
<ammountofbooks>1</ammountofbooks>
but that’s what you tell it to produce. if you want just the amount, for-each is the wrong way to go.
TheJoey
04-20-2010, 02:19 PM
Well i dont know how else i can apply it to multiple nodes...
any ideas?
Dormilich
04-20-2010, 02:35 PM
read the manual! the count() function expects a nodeset (i.e. an XPath expression), of which it counts the numbers.
TheJoey
04-20-2010, 03:50 PM
I read the manual, and it just suggest that its count(node)
my xpath isnt the best but something like
xpath = //xml/bookoptions1/
<ammountofbooks>
<xsl:value-of select="count( //xml/bookoptions1/)"/>
</ammountofbooks>
Dormilich
04-20-2010, 07:45 PM
looks promosing. does it give the desired result?
TheJoey
04-21-2010, 04:08 AM
<xml>
<bookoptions1>
<book> abc </book>
<book>abccc </book>
<book> hghghg </book>
<ammountofbooks> ??????? </ammountofbooks> (want this to count the ammount of book elements)
</bookoptions1>
<bookoptions2>
<book> abc </book>
<book>abccc </book>
<book> hghghg </book>
<ammountofbooks> ??????? </ammountofbooks> (want this to count the ammount of book elements)
</bookoptions2>
<xml>
were its just displaying 8 for both ammount of books..
Dormilich
04-21-2010, 04:16 AM
you need a different XPath for each: //bookoptions1/book and //bookoptions2/book*
* - it may differ depending on the implementation
TheJoey
04-21-2010, 01:42 PM
Thats were i thought i could use a for-each.
i have more then 60-70 bookoptions
there has to be another way..
Dormilich
04-21-2010, 02:04 PM
you could of course use it inside a template/for-each, so the counting itself becomes independend but you need an idea, how to call these templates.
<xsl:template name="bookoption">
<ammountofbooks>
<xsl:value-of select="count(./book)"/>
</ammountofbooks>
</xsl:template>
TheJoey
04-21-2010, 02:26 PM
I give up.. dorm thanks for your help.. i seem to apply it so many times so many different ways and get the same thing its so frustrating.
Thanks though i have some other issues with xpath if i could get some help on those?
select="//bookoption/find[./text()=$find]/../search">
it works almost perfectly besides the fact that it will make to many duplicates.
Dormilich
04-21-2010, 02:41 PM
try
<xsl:template match="/">
<root>
<xsl:for-each select="/xml/*">
<xsl:call-template name="bookcount"/>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template name="bookcount">
<ammountofbooks>
<xsl:value-of select="count(./book)"/>
</ammountofbooks>
</xsl:template>
TheJoey
04-21-2010, 03:06 PM
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="/xml/*">
<xsl:call-template name="bookcount"/>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template name="bookcount">
<ammountofbooks>
<xsl:value-of select="count(./book)"/>
</ammountofbooks>
</xsl:template>
</xsl:stylesheet>
i put that in and got errors
Error at xsl:template on line 4 of :
XTSE0010: An xsl:template element must not contain an xsl:template element
Error at xsl:template on line 4 of :
XTSE0010: Element must be used only at top level of stylesheet
Error at xsl:call-template on line 11 of :
XTSE0650: No template exists named bookcount
Failed to compile stylesheet. 3 errors detected.
Dormilich
04-21-2010, 03:18 PM
my XSL parser does not complain, I can’t (visually) see anything faulty either.
besides, line #4 in this code snippet is empty.
TheJoey
04-21-2010, 03:32 PM
can it be done without the template call up?
mine complains, which must follow my work requirement. sorry for doing this to you dorm
Dormilich
04-21-2010, 03:54 PM
it can be done without template, but what confuses me is the error message. it says something about nested templates, but there ain’t any. additionally, the mentioned lines do not match the code snippet at all, line 11 is not <xsl:call-template>.
TheJoey
04-21-2010, 04:00 PM
yeah im really not sure ive tried it over and over, it doesnt like to use call-template ive tried using them a few times and its always thrown up a error
Dormilich
04-21-2010, 04:19 PM
post (or PM) the complete XSL, so I can have a look on my own. btw. which parser do you use?
TheJoey
04-21-2010, 04:26 PM
i use saxon8
Dormilich
04-21-2010, 04:45 PM
from what you sent, the XML is invalid (last line should be </xml>, not <xml>)
I used Saxon 9B without problems
TheJoey
04-21-2010, 04:54 PM
its not even the xml giving me the errors, its the errors
XTSE0010: An xsl:template element must not contain an xsl:template element
XTSE0010: Element must be used only at top level of stylesheet
XTSE0650: No template exists named bookcount
Well dorm could you mabye point me in another way to do it, and is ur saxon working on windows?
edit install saxon on windows and still wouldnt work for me
just to clarify things this was the code right?
<xsl:stylesheet>
<xsl:template match="/">
<root>
<xsl:for-each select="/xml/*">
<xsl:call-template name="bookcount"/>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template name="bookcount">
<ammountofbooks>
<xsl:value-of select="count(./book)"/>
</ammountofbooks>
</xsl:template>
</xsl:stylesheet>
Dormilich
04-21-2010, 05:13 PM
its not even the xml giving me the errors, its the errors
XTSE0010: An xsl:template element must not contain an xsl:template element
XTSE0010: Element must be used only at top level of stylesheet
XTSE0650: No template exists named bookcount
a complete mystery to me
Well dorm could you mabye point me in another way to do it, and is ur saxon working on windows?
no, it’s working in Firefox/Mac
edit install saxon on windows and still wouldnt work for me
just to clarify things this was the code right?
yupp, that’s the code.
to make an immediate fix, just do by hand what the named template makes automaticly.
TheJoey
04-21-2010, 05:22 PM
DORM!!!
downloaded a new version of saxon and it parsed and made it!
thank you! :)
Dormilich
04-21-2010, 05:23 PM
glad it worked out like that.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.