Pages

Monday, September 13, 2010

BoomBox a side project...

Recently I've been playing with jquery and python. Panos and I have created Boombox, a site providing Greek music and in general music that's popular in Greece. Check it out!

Tuesday, September 7, 2010

XSLT recursion

XSLT sometimes can be a pain in the bum, for sure it's not one of my favorite languages. :)

So today, I was trying to fix the following problem:

XML snippet looked like this:

<tag1>
  text 1
  <tag11>
    <tag12>text 2</tag12>
  </tag11>
  text 3
  <tag21>
    text 4
    <tag22>text 5</tag22>
  </tag21>
  text 6
</tag1>

I wanted my output to look like this:

text 1 text 2 text 3 text 4 <a href="blah">text 5</a> text 6.

So pretty much what I needed to do was to get the text value of each node except from tag22 node, in which case I wanted to apply a template and output it as an anchor tag.

Here is the XSLT snippet which produces the desired result:

<xsl:apply-templates select="tag1" mode="foo"/>
<xsl:template match="text()" mode="foo">
  <xsl:value-of select"."/>
</xsl:template>
<xsl:template match="*" mode="foo">
  <xsl:apply-templates mode="foo"/>
</xsl:template>
<xsl:template match="tag22" mode="foo">
  <a href="blah"><xsl:value-of select="."/></a>
</xsl:template>

Let me try to explain whats going on here.

  1. mode=foo : mode is a pretty usefull attribute with XSLT, if an xsl:apply-templates element has a mode attribute, then it applies only to those template rules from xsl:template elements that have a mode attribute with the same value; if an xsl:apply-templates element does not have a mode attribute, then it applies only to those template rules from xsl:template elements that do not have a mode attribute. We need the mode attribute in this case because, we need to override the default behavior when matching all tags under tag1.
  2. match=text() : this is a NodeType test, this instruction will be matched for text nodes, in which case we'll just output their values (text itself)
  3. match=* : this will initially match any node which is first level child of tag1. After that we recursevily call <xsl:apply-templates mode="foo">, to apply matching templates for all descendants of tag1's first level children. So we will keep applying templates until we reach a leaf, in which case we'll output its content.



References: