Subject: RE: template match : node-set paring through multiple-axis relationships
From: "Lars Huttar" <lars_huttar@xxxxxxx>
Date: Tue, 3 Jun 2003 15:46:18 -0500
|
Jonathan wrote:
> From message
> (http://www.biglist.com/lists/xsl-list/archives/200305/msg01198.html)
>
> Discouraged by XSL's limitations, I gave up doing it the nice
> way and hacked
> my own solution. In case you care, here it is. It is a pain
> in the bum,
> because now I have to create a bunch of variables, and do my own name
> mangling if I have two different things to do to a 'b' in two
> different
> contexts because XSL's namespace is intuitively different
> from conventional
> namespaces in C++. However, it works,
Your solution may work, but didn't you violate the constraint that
made your original question tricky -- that it had to be done
using just a template match pattern (no "if"s -- and so presumably
no "choose"s)?
> and I can generate it generically
> from a graphical transformation language.
> For those who are in charge, and using this list to educate
> others on XSL to
> evangelise it to the world on XSL and its usage, I am
> disappointed that no
> one responded to my request, even to say "boy, that sure is a
> different
> problem". :(
Whether a given question gets answered on this list tends to be
pretty hit-and-miss. In any case 3 business days is not a very long
time to wait. People on the list desire to help, but noone
may notice if a particular question goes unanswered (it takes
work to notice a negative!).
However, it is an interesting question, if only because
of your original constraint that it had to be done entirely within
the match pattern. I think you're probably right that it's
impossible due to the limitations of XSLT 1.0. But I'd be
interested to hear if anyone can prove that. I also wonder whether
it would be possible in XSLT 2.0.
With that constraint removed, the problem could be solved as you did,
or a more readable solution would be:
<xsl:template match="b">
<xsl:variable name="uncle-b" select="../../b"/>
<xsl:variable name="src-c" select="//c[c1[@role='src' and
@target = current()/@id]]" />
<xsl:variable name="dest" select="id($src-c/c1[@role='dst']/@target)" />
<xsl:choose>
<!-- Do nodesets $uncle-b and $dest overlap? -->
<xsl:when test="count($uncle-b) + count($dest) > count($uncle-b | $dest)">
<xsl:call-template name="WhatToDoWithMy_B_Now"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="different" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
But since you're generating code, maybe readability is not one
of your priorities.
> It is unacceptable to defer any testing to an "if" command
> inside the template, because failure in the "if" command leaves me no
> alternatives to match, and this 'b' node may require other processing if the
> match is not made.
If I understand what you're saying, wouldn't it fit your needs
to have an "otherwise" that applies templates to . in a different mode?
(as above)
Then you can have all the other kinds of template matching you want
for b nodes, e.g.
<xsl:template match="b[conditions]" mode="different">
...
</xsl:template>
> <xsl:when test="current()[$b2][$focus][//c[c1[@role='dst']
> [@target=$b2/@id]][c1[@role='src'][@target=$focus/@id]]]">
As David Carlisle mentioned, this expression is pretty strange.
A more natural way to do it would be:
<xsl:when test="//c[c1[@role='dst' and @target=$b2/@id]]
[c1[@role='src' and @target=current()/@id]]]">
As David mentioned, [$focus] is always true, and [$b2] must
be true if the third predicate (the big one) is true, because
the latter depends on $b2/@id being non-empty.
Lars
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|