Re: [xsl] PARAMS and VARIABLES in XSL

Subject: Re: [xsl] PARAMS and VARIABLES in XSL
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Tue, 30 Jan 2007 21:04:21 +0100
mark bordelon wrote:
I need help with the following problem.

This is the XML is wish to transform:


I have tried all sorts of solutions using axes,
preceding-sibling, but these did not work, since the
<word> and <sound> are not true siblings to the
processor, even though they are on the same level of
the hierarchy.

Well, if you mean with "not true siblings" that you have missed the closing tag, you are out of luck: it is not XML.


But you just made a copy n paste mistake, and each sound tag is an empty tag, here's your solution:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
<xsl:output indent="yes" />
<xsl:template match="word">
<word soundtime="{preceding-sibling::sound[1]/@time}">
<xsl:value-of select="." />
</word>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>



The delete-template for text() is one way to get rid of the whitespace that would otherwise be output (but is not necessary with your input).


To make this work, you must first make XML from your input.


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; >
<xsl:template match="//clause/*">

As a general rule: never start a match with "//". It is not necessary for any reason. Just 'clause/*' would do if you want to match all nodes that have a parent 'clause' (which is not what you want, I think).


<xsl:param name="soundtime" />
<xsl:if test="local-name() = 'sound'">
<xsl:param name="soundtime" select="@time" />
</xsl:if>

Somehow this looks like trying to redefine a parameter. Which is not allowed, ever. Using 'local-name()' is redundant. If you want to test for a node that is there, just do:


<xsl:if test="sound" >....


<xsl:if test="local-name() = 'word'">

same here


<word sound = "{$soundtime}" >

You may be falling in the trap of thinking as XSLT as a 'normal' language, where 'normal' is defined as "take variable X, assign it value Y, read out variable X, assign it another value Z, do something else... etc". Which is the Java, VB, C++ etc way of doing things.


Not so in XSLT. Assignment of variables is not possible at all. Here you define the rules and the processor does the thinking for you. If you find yourself making many xsl:if and xsl:choose, you are probably missing something vital somewhere. A rule is defined like:

<xsl:template match="somenode">
  ... DO something IF this node is encountered in the source


To select what set of nodes you want to process, you use xsl:apply-templates + select.



Cheers, -- Abel

Current Thread