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[(_at_)role='src' and
@target =
current()/@id]]" />
<xsl:variable name="dest" select="id($src-c/c1[(_at_)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[(_at_)role='dst']
[(_at_)target=$b2/@id]][c1[(_at_)role='src'][(_at_)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[(_at_)role='dst' and @target=$b2/@id]]
[c1[(_at_)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