Connecting Tech Pros Worldwide Help | Site Map

XSLT increment

Newbie
 
Join Date: Nov 2008
Posts: 5
#1: Nov 18 '08
Hi
I have a number of variables which I want to use in svg diagrams for coordinates. And some of these coordinates have to increment or decrement as need be, for each iteration in the <for-each> loop.
I know xslt variables cant be changed once assigned a value. But I think there is a way to get around it by making templates. But I am not really sure how to do that.
Could somebody help?
Dormilich's Avatar
Moderator
 
Join Date: Aug 2008
Location: Leipzig, Germany
Posts: 3,629
#2: Nov 19 '08

re: XSLT increment


simply redefine it.
Expand|Select|Wrap|Line Numbers
  1. <xsl:variable name="test">1</xsl:variable>
  2. // some code...
  3. <xsl:variable name="test" select="$test + 1"/>
regards

PS: I think w3schools.com's note about not being able to change a variable value is a mistake, I didn't find any such note in the specs.
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#3: Nov 19 '08

re: XSLT increment


Pure XSLT doesn't allow you to reassign variables. You'll get a compilation error if you do it that way. (variable already exists within that scope)
Options:
1. Have you tried using <xsl:number/> ?
http://www.w3schools.com/xsl/el_number.asp
2. Another way is to use a recursive template.
3. Depending on what you're doing, you may be able to use a combination of count() or sum(), and preceding:: axis.
4. If you're using saxon, you can cheat using an extension.
http://saxon.sourceforge.net/saxon7....l#saxon:assign
Newbie
 
Join Date: Nov 2008
Posts: 5
#4: Nov 19 '08

re: XSLT increment


thanks for your reply.
- Dont know how to use xsl:number for this situation
-How would recursive template help in situation, I dont want a number to increment a number of times in one template at the same time. I want every time the control goes in the for-each, it should increment by 10( or some other number). Shouldnt I be calling one template from another. May be its the programmer in me which is thinking this way. Not really sure how to accomplish the task.
-also dont know how to use count() and sum() for this task

Please throw some more light
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#5: Nov 19 '08

re: XSLT increment


Can we see your current xml, xslt, and expected result?
Please simplify where possible.
Newbie
 
Join Date: Nov 2008
Posts: 5
#6: Nov 19 '08

re: XSLT increment


Quote:

Originally Posted by jkmyoung

Can we see your current xml, xslt, and expected result?
Please simplify where possible.

I'll try to simplify although that wont be easy.
I have an xsql file which queries the db and throws the result in XML format. This generated xml file would be displayed in terms of xml diagrams(using svg and xslt) on the browser.
So I dont have the xml file as such because its generated at run time.
The xsl file is as under:
Expand|Select|Wrap|Line Numbers
  1.  
  2. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  3. <xsl:template match="/">
  4.  
  5. <xsl:variable name="x" select="500"/>
  6. <xsl:variable name="y" select="200"/>
  7. <xsl:variable name="rx" select="5"/>
  8. <xsl:variable name="ry" select="5"/>
  9. <svg:svg xmlns:svg="http://www.w3.org/2000/svg" viewBox="100%">
  10. <xsl:for-each select="/somenode">
  11.  
  12. <svg:rect x="{$x}" y="{$y}" rx="{$rx}" ry="{$ry}" width="40" height="60"
  13. fill="red" stroke="none"></svg:rect>
  14. <svg:text font-family="Verdana" font-size="6" fill="black">
  15. <xsl:value-of select="node_name"/>
  16. </svg:text>
  17.  
  18. <!-- here I would like to decrease x and y values by some constant numbers , so that for next iteration the values are somewhere aound 480 and 190 respectively. Right now I am getting all the rectangles overlapping on each other because the x and y coordinates remain the same. Instead, I want to have kinda stacked view of the rectangles.
  19.  
  20. -->
  21.  
  22. </xsl:for-each>
  23.  
  24. </svg:svg>
  25. </xsl:template>
  26. </xsl:stylesheet>
  27.  
So when I view source from the browser, I see lots of rectangle elements and different node_names for each of those, but same x and y coordinates.

View Source/ xml file after applying existing xslt:--

Expand|Select|Wrap|Line Numbers
  1.  
  2. <?xml version = '1.0' encoding = 'UTF-8'?>
  3. <svg:svg viewBox="100%" xmlns:svg="http://www.w3.org/2000/svg">
  4.  
  5. <svg:rect x="500" y="200" rx="5" ry="5" width="40" height="60" fill="red" stroke="none"/>
  6. <svg:text font-family="Verdana" font-size="6" fill="black">nodename1</svg:text> <!-- End of first iteration-->
  7. <svg:rect x="500" y="200" rx="5" ry="5" width="40" height="60" fill="red" stroke="none"/>
  8. <svg:text font-family="Verdana" font-size="6" fill="black">nodename2</svg:text> <!-- End of second iteration-->
  9. <svg:rect x="500" y="200" rx="5" ry="5" width="40" height="60" fill="red" stroke="none"/>
  10. <svg:text font-family="Verdana" font-size="6" fill="black">nodename3</svg:text> <!-- End of third iteration-->
  11.  
  12. </svg:svg>
  13.  
I hope I am clear in describing my specific problem

Thanks
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#7: Nov 20 '08

re: XSLT increment


Could you use the position function then? eg something like:
<svg:rect x="{$x- position() * 40}" y="{$y - position() * 60}" rx="{$rx}" ry="{$ry}" width="40" height="60"
Newbie
 
Join Date: Nov 2008
Posts: 5
#8: Nov 21 '08

re: XSLT increment


Just before looking at your comment I successfully tried exactly the same thing and it worked out. Instead of decrementing I incremented it by some value. Thanks a lot for your help. The only thing I would love to hear is that how would I put same logic in the form of a template, so that it can be generalized and used for a number of diagrams.
Moderator
 
Join Date: Mar 2006
Posts: 1,103
#9: Nov 21 '08

re: XSLT increment


Just swap out the numbers you're multiplying by with another variable.
Newbie
 
Join Date: Nov 2008
Posts: 5
#10: Nov 25 '08

re: XSLT increment


Thanks a lot again !
Reply