RE: [xsl] template match : node-set paring through multiple-axis relationships

Subject: RE: [xsl] 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


Current Thread