Re: [xsl] Getting variable yet most immediate parentNode
Subject: Re: [xsl] Getting variable yet most immediate parentNode|
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Thu, 27 Sep 2007 22:40:56 +0200
Problem: given the variable relationship between the <answer> nodes
being matched and their parent <section>, how to reliably amtch the
correct section @name?
<xsl:apply-templates select="../../../answers" >
<xsl:with-param name="qKey" select="@key" />
I'm sorry to not have looked into your problemm as I lack the time at
the moment, but consider the structure above, you have lots of them.
Whenever you find yourself writing something like that, think again and
start refactoring right away to make your code easier to read *and*
remove redundancy. The redundancy in the above code is the "if nodex
then apply nodex", which can simple be rewritten as "apply nodex":
applying templates to something that is not there is applying something
to nothing is nothing. Hence: the if-statement is redundant.
Rewrite the above as (totally without the xsl:choose!):
<xsl:apply-templates select="../../../answers" />
In addition, you have three ways of writing 'answers': ,../answers,
../../answers and ../../../answers. I am sure that while you were
writing it you were thinking something like "it must be possible to
achieve this effect more easily"... There are several ways to code
around the path-depth problem, but the easiest is probably to leave the
path out completely, if you are certain that "answer" elements are what
they are at any level: answer elements (and even if you do find later
that you have different treatment for different answer-elements, you
will simply add a new rule):
I ususally advise against it, but this is a good place to code:
<xsl:apply-templates select=".//answers" />
.... your logic here
That's all you need! Much easier than the unmaintainable and
ununderstandably long xsl:choose, no?
Same with the following bit. You wrote:
<xsl:otherwise><xsl:value-of select="." /></xsl:otherwise>
This statement is exactly equal to (if you use xslt 2.0):
<xsl:value-of select="(@name, .)" />
But in general is better written out in rules, which are easier to follow:
<xsl:apply-templates select="@name | ." />
<xsl:template match="option/@name"><xsl:value-of select="." /></..
<xsl:template match="option[not(@name)]"><xsl:value-of select="." /></...
Later in your stylesheet you go on and on trying to understand the logic of the difficult input xml and feed it to the xslt processor. But why don't you turn it around? Define the rules in matching templates and you will see that your stylesheet becomes both easy to write and easy to maintain / adjust.
A good introduction on how to understand the template matching principles are Jeni Tennison's books, she has several, but her intro's on XSLT 1.0 and XSLT 2.0 (two separate books) are excellent (biases opinion from me).
Have fun with coding, make it yourself easy! ;)
-- Abel Braaksma --