[xsl] templates as functions that return a context?

Subject: [xsl] templates as functions that return a context?
From: Joern Nettingsmeier <nettings@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 24 Feb 2006 17:15:09 +0100
hi everyone!


sorry if this is a FAQ, but i couldn't think of any more search terms for this problem... at least i hope it's interesting.



i'm trying to write an xslt that converts a relax ng grammar into a cocoon forms description for a web application (if you are not familiar with cforms, think of a simple html form).


to do that, i think i need to walk the tree both forwards and backwards.

i want to contain all "understanding" of relax ng semantics in named templates that each implement one particular functionality (this works) and are able to pass their result contexts to each other (this doesn't).

here's a very simple relax ng example:

<grammar>
  <start>
    <element name="phone">
       <optional>
          <element name="countryprefix">
             <text/>
          </element>
       </optional>
       <element name="areacode">
          <text/>
       </element>
       <element name="localnumber">
          </text>
       </element>
    </element>
  </start>
</grammar>

i'm matching leaf nodes ("<text/>" in this example), which correspond to form fields in my output.

before i can build a form, i need to know whether this particular leaf is optional, and what the name and ID of the field should be. to do that, i walk the tree back up:

<xsl:template name="getOutputNode">
  <!-- is this already an output node? -->
  <xsl:choose>
    <xsl:when test="self::rng:element|self::rng:attribute">
      <xsl:value-of select="self::node()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:for-each select="parent::node()">
        <xsl:call-template name="getOutputNode"/>
      </xsl:for-each>
    </xsl:otherwise>	
  </xsl:choose>
</xsl:template>

the template returns a RTF that is readily converted to a node-set with exsl:node-set(), and i now can get the @name of the surrounding <element>.

the hard part: get the field id.

when i run generate-id() on it, the result will be meaningless because i'm working on a temporary tree.

the question is: is there a way to find a particular node in the tree with a named template, and return it in *context*, so that other templates can operate on this node *as part of the original tree*?

i don't want to "mark" the source tree i a way that would violate the "no side effects" rule of xslt.

any xpath function can do that. why can't templates? and how can i work around it? are xslt2.0 functions the way? and if so, can you recommend an implementation?


best regards,


jC6rn


-- jC6rn nettingsmeier

home://germany/45128 essen/lortzingstr. 11/
http://spunk.dnsalias.org
phone://+49/201/491621

if you are a free (as in "free speech") software developer
and you happen to be travelling near my home, drop me a line
and come round for a free (as in "free beer") beer. :-D

Current Thread