Feature Request - Node Set Processing (long)

Subject: Feature Request - Node Set Processing (long)
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 12 Jan 1999 17:02:43 -0500
I've come to need a new feature in XSL and though I'm willing to concede it
may appear complex, I would find such a feature incredibly useful, and I
hope the committee would consider its inclusion in a future WD.

In my XSL work, I have found it useful to consider sets of nodes created by
a select statement, and operations on that set using as a focus, the
current node in the source tree.

First, I'll describe how I've accomplished my needs using a post process,
and then I'll describe my requirements for a new feature of XSL.  I then
attempt to divine a syntax for this new feature, though I will of course
defer to the expertise of the committee and their knowledge of all
requirements to come up with an appropriate syntax if they deem the
requirements sufficiently worthwhile.

I hope to convince you this powerful feature would supplant the need for
complex scripting in a particularly situation that I would think might be
quite common if people realized what they could do with the feature.

Introduction:
------------

I'm creating some XSL training materials, and each generated HTML slide
from a set of slides has a number of navigation buttons.  In the top right
corner, I have a nine-button panel that navigates the user from the current
page as follows:

   prev-module     course-home     next-module

   prev-lesson     this-module     next-lesson

   prev-pane       this-lesson     next-pane

In the bottom center, I have a button-bar that navigates the user to
arbitrary points in the materials:

         module-1  module-2  module-3 ...... module-15

   m1-lesson-1 m1-lesson-2 m2-lesson1 ..... m15-lesson-3 m15-lesson4

Current Solution (Work-around):
------------------------------

Since I'm using the ID attribute to guarantee filename uniqueness, it
happens that all the nodes I'm interested in have a unique attribute value
... so I'm keying on that unique value in my post processes as if it were a
node identifier.

I use a DSSSL post process that accepts, for each button, the XSL
generation of the name of the current node, the names of nodes in a "set of
nodes", a relationship type, a result tree for relationship success, and a
result tree for relationship failure.

Using a select statement for my set criteria, I can create an arbitrary set
of members for testing purposes:

  <xsl:apply-templates select="/course/intro|
                               /course/lesson|
                               /course/exit">
    ... note membership in set ...
  </xsl:apply-templates>

... this creates my set in the order desired out of any nodes from anywhere
in the entire source tree.

My current node is considered for this operation the test node, and it is
passed on to the post-process using its ID attribute.

I then describe two result templates, one tree for use in a "success
relationship" and the other in a "failure relationship" (relationship
described below).  Since I can't describe a template for output (I have no
where of marking the placeholders for operations on the node), I have built
the template into my post process and synthesize the result tree based on
processing the node in the set whose ID attribute is (success) or is not
(failure) related to the test node.


The post process iterates over the set in order, testing the relationship
between the member of the set node and the test node, and for each
operation determines a success condition and a failure condition.  Most
operations result in a single condition, though there is an operation that
results in as many conditions as there are members of the set.
So far I have used 4 types of relationship, but I'm sure there could be
others.  The four I've needed to date are:

    "prev"
      - the test node is in the set
      - there exists a node in the set prior to and adjacent to the first
member in the set that is the test node
      - success: - single result tree fragment if all criteria are met,
using the prior adjacent node for focus as if the result of a select pattern
      - failure: - single result tree fragment if any criterion is not met,
using the test node for focus as if the result of a select pattern

    "next"
      - the test node is in the set
      - there exists a node in the set following and adjacent to the first
member in the set that is the test node
      - success: - single result tree fragment if all criteria are met,
using the following adjacent node for focus as if the result of a select
pattern
      - failure: - single result tree fragment if any criterion is not met,
using the test node for focus as if the result of a select pattern

    "this"
      - the test node is in the set
      - success: - single result tree fragment if all criteria are met,
using the test node for focus as if the result of a select pattern
      - failure: - single result tree fragment if any criterion is not met,
using the test node for focus as if the result of a select pattern

    "all"
      - the test node may or may not be in the set, any number of times
      - the XSL engine iterates over the members of the set, in order, and
determines a success condition testing if the member node of the set is
(success) or is not (failure) the test node
      - for each success: - single result tree fragment if all criteria are
met, using the test node for focus as if the result of a select pattern
      - for each failure: - single result tree fragment if any criterion is
not met, using the test node for focus as if the result of a select pattern
      
Possible other relationships (but I haven't needed yet in my work):

    "type" 
      - the element type of the member node of the set is the same as the
element type of the test node
    "ancestor"
      - the member node is an ancestor of the test node
    ".." 
      - the member node of the set is the parent of the test node
    "child"
      - the member node is a child of the test node
    "descendant"
      - the member node is a descendant of the test node

Using the above, I'm successfully creating both navigation techniques on
all of my tutorial slides.

Requirement:
-----------

To specify alternative success/failure result tree templates to be applied
to either the current node in the source tree or a member of a set of
nodes, based upon a relationship existing between the current node and the
members of the set of nodes.

A Possible Syntax:
-----------------


    <xsl:choose select="[SelectExpr]" test="[Type]">
      <xsl:when>
      </xsl:when>
      <xsl:otherwise>
      </xsl:otherwise>
    </xsl:choose>

- either both select= and test= are specified or neither are specified
- when both are specified, there exists at most one <xsl:when> child and it
has no test attribute
- the problem using "test=" as above, is it may confuse new users that the
existing test criteria
- possibly split my conceptual test into two attributes, "test=" and
"iterate=[yes/no]", and use an extended set of select patterns:

    test=".[any-of-type()]"       <!--same element type name-->
    test=".[next-of-type()]"      <!--next node in set with same type-->
    test=".[next-of-any()]"       <!--"next"-->
    test="ancestor(...)"          <!--"ancestor"-->
    test=".."                     <!--"parent"-->
    test="."                      <!--"this"-->
    test="/*"                     <!--"child"-->
    test="//*"                    <!--"descendant"-->

- the "all" I've documented above would be: test="." iterate="yes"

Example:
-------

   <xsl:choose select="/course/intro|
                       /course/lesson|
                       /course/exit"
               test="."
               iterate="yes">
     <xsl:when>
       <xsl:apply-templates mode="green-jump" select="."/>
     </xsl:when>
     <xsl:otherwise>
       <xsl:apply-templates mode="red-jump" select="."/>
     </xsl:otherwise>
   </xsl:choose>

Conclusion:
----------

Instantiating result templates based on set behaviour can be a powerful
construct, eliminating the need for possibly complex scripting.  This
proposal extends the functionality of XSL in a useful way, possibly without
adding any new actions to the vocabulary.

.......... Ken


--
G. Ken Holman         mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.  http://www.CraneSoftwrights.com/s/
Training:   http://www.CraneSoftwrights.com/s/schedule.htm
Resources: http://www.CraneSoftwrights.com/s/resources.htm
Shareware: http://www.CraneSoftwrights.com/s/shareware.htm
Next XSL Training (see training link):   WWW8 - 1999-05-11


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread