[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Ignoring ambiguous matches


Subject: Re: [xsl] Ignoring ambiguous matches
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxx>
Date: Thu, 13 Feb 2014 12:53:30 -0500

Ihe,

What this has over the next-match based solution is essentially in its
maintainability, extensibility and flexibility as the complexity of
the problem grows.

Of course you could do the same with XSLT stylesheet functions. As
long as they return nodes:

$context/ihe:process1(.)/ihe:process2(.)/ihe:process3(.)

or even if they don't (in 3.0):

$context ! ihe:process1(.) ! ihe:process2(.) ! ihe:process3(.)

The visitor pattern only exposes this logic to make it easier to (re)configure.

As for missing language features -- my approach has always been a
pragmatic one, and XSLT in all its versions has always contained a
strong dose of the pragmatic, so I have been happy. XSLT 3.0 gives us
functions as first-class objects and that will presumably put this to
rest for you or help to do so (although I dare say people will always
have complaints). Yet I have always been more interested in making
things work with what we have than in speculating about possible
worlds in which we do not actually live. Even when I indulge in
speculation, part of me is always looking back at me from my shoulder
to ask so what.

Cheers, Wendell

On Thu, Feb 13, 2014 at 11:51 AM, Ihe Onwuka <ihe.onwuka@xxxxxxxxx> wrote:
> On Thu, Feb 13, 2014 at 4:34 PM, Wendell Piez <wapiez@xxxxxxxxxxxxxxx> wrote:
>> Hi Ihe,
>>
>
> Hi Wendell,
>
>>
>> Function composition, yes ... when faced with problems like this I
>> have sometimes resorted to a "visitor pattern". This is a technique
>> inspired by Dimitre's ingenious implementation of FXSL.
>>
>
> The visitor pattern. Have read a whole book on the thing
> http://www.amazon.com/Little-Java-Few-Patterns/dp/0262561158/ref=sr_1_1?ie=UTF8&qid=1392309788&sr=8-1&keywords=a+little+java+a+few+patterns
> and had to code it in compiler class.
>
> I still couldn't explain it's whys or wherefores to you.
>
>
>> The idea is to bind each process to an element, something like so:
>>
>> <xsl:template match="data">
>>   <xsl:variable name="processes" as="element()+">
>>     <ihe:process1/>
>>     <ihe:process2/>
>>     <ihe:process3/>
>>   </xsl:variable>
>>   <xsl:apply-templates select="$processes">
>>     <xsl:with-param name="context" select="."/>
>>   </xsl:apply-templates>
>> </xsl:template>
>>
>> Then deploy templates to match the elements in the 'ihe' namespace to
>> execute your processes.
>>
>> This is really good for managing, for example, sets of tests that have
>> to be performed over your data.
>>
>> In your case it sounds like there is an additional requirement: each
>> process needs, as input, not the original matched element, but the
>> results of other processes.
>>
>> For that, work one process at a time, passing the results forward:
>>
>>   <xsl:apply-templates select="$processes[1]">
>>     <xsl:with-param name="results-so-far" select=".">
>>     <xsl:with-param name="processes-remaining"
>>        select="remove($processes,1)"/>
>>   </xsl:apply-templates>
>>
>> Your receiving templates (matching in the 'ihe' namespace) must know
>> how to pass their results forward into the first process in the
>> $processes-remaining stack, or to return their results instead when
>> $processes-remaining is empty, something like:
>>
>> <xsl:template match="ihe:process1">
>>   <xsl:param name="results-so-far" required="yes"/>
>>   <xsl:param name="processes-remaining" select="()"/>
>>   <xsl:variable name="new-results">
>>     ... do your thing ...
>>   </xsl:variable>
>>   <xsl:choose>
>>     <xsl:when test="empty($processes-remaining)">
>>       <xsl:sequence select="$new-results"/>
>>     </xsl:when>
>>     <xsl:otherwise>
>>       <xsl:apply-templates select="$processes-remaining[1]">
>>         <xsl:with-param name="results-so-far" select="$new-results"/>
>>         <xsl:with-param name="processes-remaining"
>>            select="remove($processes-remaining,1)"/>
>>     </xsl:otherwise>
>>   </xsl:choose>
>> </xsl:template>
>>
>> Using this method, priority setting is not needed; the order of
>> processes is indicated by their sequence order.
>>
>> That being said, the overhead (syntactic and conceptual) is high
>> enough that it may not be worth it except as the complexity of the
>> problem goes up. It does support arbitrary mixing and matching of data
>> to processes; and exposing the processes by binding them to their
>> proxy elements may have other advantages.
>>
>
> I'm guessing this was conceived from XSLT 1.0 because I am trying to
> see what it has over the next-match based solution (granted that may
> have required explicit priority settings) - I never did try it in the
> end - pressure of deadline.
>
> Is this not a graphic illustration of Norvig's point  though - pattern
> usage necessitated by what was a missing language feature?
>
>> I hope this helps.
>>
>> Cheers, Wendell
>>
>> --
>> Wendell Piez | http://www.wendellpiez.com
>> XML | XSLT | electronic publishing
>> Eat Your Vegetables
>> _____oo_________o_o___ooooo____ooooooo_^
>



-- 
Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables
_____oo_________o_o___ooooo____ooooooo_^


Current Thread
Keywords