Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't stop thinking about XSLT in procedural terms... help with apply-templates

Tags:

xslt

I know that XSLT does not work in procedural terms, but unfortunately I have been doing procedural languages for too long. Can anyone help me out by explaining in simple terms how things like apply-templates works and help a thicko like me to understand it.

like image 386
Xetius Avatar asked Dec 18 '22 10:12

Xetius


1 Answers

What makes you think that procedural terms do not apply here? It's just that the calling convention is somewhat more implicit than you would traditionally expect it, because there is an invisible context involved. Everything apply-templates does could be expressed in procedural terms.

Basically, apply-templates is nothing more than a for-each loop. Starting from where where you currently are in the document (the context, think "this"), it iterates over the child nodes.

For each child, the processor selects the matching xsl:template with the highest priority (based on their respective match and priority attributes), sets the context to the child at hand and runs this template (think "function"). After the template returns, the context snaps back and it's the next child's turn.

Even when things become recursive (which is somewhat hard to avoid in XSLT), the whole process really does not become any more complicated. The context "pointer" is moved around, and templates get called.

You can restrict the node set that apply-templates iterates over, using the select attribute:

<!-- all children of the context node regardless -->
<xsl:apply-templates />  

<!-- all children of the context node being "data" with a @name of "Foo" -->
<xsl:apply-templates select="data[@name='Foo']" />  

You can sort the node-set prior to the iteration, if you wish:

<!-- all children of the context node being "data" with a @name of "Foo",
     ordered by their respective "detail" count -->
<xsl:apply-templates select="data[@name='Foo']"> 
  <xsl:sort select="count(detail)" data-type="number" order="descending"/>
</xsl:apply-templates>

And you can pass parameters to your template if you need, just like you would with a regular function call:

<!-- pass in some parameter -->
<xsl:apply-templates select="data[@name='Foo']"> 
  <xsl:with-param name="DateSetIcon" select="$img_src" />
</xsl:apply-templates>

That's about all there is to it.

EDIT:

I know that the last comment is a bit provocative. This is very much intentional, for a basic understanding of how apply-templates works this is more or less it. The implications and possibilities that come from the fact that not you are defining what template to call, but rather let the processor choose the right one for you are of course bigger than what it sounds like to the untrained ear. The declarative/implicit approach of the whole thing surely needs some time to sink in.

like image 89
Tomalak Avatar answered May 16 '23 03:05

Tomalak