Monday, January 23, 2006

XSL Whitespaces...

Remember the piece of code you put in at the head of an XSL to preserve white spaces.? Well it does preserve whites if you have any midway, say in your variables or parameters passed.
But what if you wanted to add a white space, in the output HTML you are generating. The same job done by a or a VbCrLf...?
Sad for beginners like us, pampered by the abundance of such variables in most languages, XSL is devoid of one.

Has a work around though...(God bless..!)
Let us say you wanted to print:
Hoodibaba, 888, BabyMamon..in the same line...

Getting the basics done with...

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:param name = "firstString" select = "Hoodibaba">
<xsl:param name = "secondString" select = "888">
<xsl:param name = "thirdString" select = "BabyMamon">

<xsl:template match="/">

<html>
<body>
<b>I am going to print 3 strings!</b>

Now if you just selected the value of these 3 parameters and printed, say like this...

<b><xsl:value-of select = "$firstString"/></b><xsl:value-of select = "$secondString"/><xsl:value-of select = "$thirdString"/>

..your output would be something like this...

Hoodibaba888BabyMamon

Not exactly lookable right..?
Thats where the idea of white spaces comes in..

We use the <xsl:text> functionality for the same.
<xsl:text> basically adds any additional text into your template that is not covered by other features.


So rewriting the above statements as....

<b><xsl:value-of select = "$firstString"/></b><xsl:text> </xsl:text><xsl:value-of select = "$secondString"/><xsl:text> </xsl:text><xsl:value-of select = "$thirdString"/>

Would give something more liek what we want....

Hoodibaba 888 BabyMamon

It preserves white spaces, remember..?
So you could also imitate the carriage return this way...

<b><xsl:value-of select = "$firstString"/></b><xsl:text>
</xsl:text><xsl:value-of select = "$secondString"/><xsl:text>
</xsl:text><xsl:value-of select = "$thirdString"/>

Would make our output look like this...

Hoodibaba
888
BabyMamon

Problems solved..eh..?

Learnings:
1....uhmmm...its the best language to work on when you like to use every single command to its fullest, what if for a mere job like a WhiteSpace..!

Loop with XSL..

The kind of language that XSL is, with nothing written straight forward and a real nightmare for once having a first glance, it has no option for looping..There is the option...Quite contrary to what it actually sounds, it has nothing to do with the for loops of other programming languages. It merely runs through each repition of a node and performs the actions.
Searching around in the net for this was no joke either, for very few got me where i wanted. And finally i got one link that seemed god sent..posted just for me..!

Posting the code here:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">

<html>
<head><title>Say Hello Ten Times!</title></head>
<body>
<b>I am going to say hello Ten Times!</b>
<!-- begin_: Call the loop function -->
<xsl:call-template name="loop">
<xsl:with-param name="i">1</xsl:with-param>
<xsl:with-param name="count">10</xsl:with-param>
</xsl:call-template>
</body>
</html>

</xsl:template>


<!--begin_: Define_The_Output_Loop -->
<xsl:template name="loop">

<xsl:param name="i" />
<xsl:param name="count" />

<!--output to be printed for every loop-->
<xsl:if test="$i <= $count">
<br /><b><xsl:value-of select="$i" />.</b>Hello World
</xsl:if>

<!--Repeat The Loop Until Finished-->
<xsl:if test="$i <= $count">
<xsl:call-template name="loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>

</xsl:template>
</xsl:stylesheet>



------------------------------------------------------------------------
learnings from this venture:

1. This is a huge workaround for a simple operation done by a for loop. Wonder why w3c dint come up with something simpler for it.
2. No new template can be defined within another. So make the call in place, and define the template elsewhere.
3. It doesnt matter whether u define the template before or after the call for template.
4. Templates rock.!