Re: [xsl] Run-time polymorphism in XSL 1.0

Subject: Re: [xsl] Run-time polymorphism in XSL 1.0
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Mon, 21 Mar 2005 13:56:22 +1100
Hi Andrey,

Yes, this is one way to simulate virtual functions. The description
seems a little-bit too-complicated.

This approach was first described (in a more simple way -- just by an
example) at:

    http://www.biglist.com/lists/xsl-list/archives/200111/msg01100.html

and later in:

    http://www.mulberrytech.com/Extreme/Proceedings/xslfo-pdf/2003/Novatchev01/EML2003Novatchev01.pdf


My personal observations indicate that such type of run-time
polymorphism is much-too clumsy and to the best of my knowledge has
not been used in a system that exploits the much more powerful,
natural and convenient mechanism of using Higher Order Functions
(HOFs).

Another stumbling block is that no type-checking can be provided in
both XSLT/XPath 1.0 *and* 2.0.

It is extremely awkward not to be able to define the necessary types
inline in a stylesheet. One has to define them separately in XSD.

 The C-Omega language gives the ability to conveniently define such
types inline and in this respect provides a better programming
environment than XSLT 2.0.

Cheers,
Dimitre Novatchev.

On Sun, 20 Mar 2005 18:51:21 -0500, Andrey Basko
<andrey_basko@xxxxxxxxxxxxxxxx> wrote:
> Hi, All!
> 
> Some time ago I tried to find reliable approach how to implement run-time
> polymorphism in XSL 1.0. Initially I used inbuilt polymorphism-like template
> overriding mechanism based on import precedence. However I encountered the
> issues described in: ("Reliance on import precedence considered dangerous"
> http://sources.redhat.com/ml/xsl-list/2001-02/msg00996.html,  and
> http://sources.redhat.com/ml/xsl-list/2001-02/msg01003.html).
> 
> In XSL forums I found several messages that mentioned how to implement
> polymorphism in XSL 1.0 based on generic templates proposed by Dmity
> Novatchev
> (http://lists.fourthought.com/pipermail/exslt/2001-May/000169.html).
> 
> Eventually I came up with some approach that I would like to share with the
> XSL community. The idea how to implement run-time polymorphism in XSL is
> similar to approach used in generic templates:
> 
> 1. Declare special customized data structures (under non-xsl namespace,
> embedded in the stylesheet) which define:
>    a. Virtual methods in logically defined class.
>    b. Virtual methods table variable by inheriting methods from virtual
> methods table of base "class".
> 
> 2. Pass reference to virtual methods table to all virtual methods as a
> parameter.
> 
> Below I describe several "how to" steps in order to explain how to declare
> two classes: Base "class" and Child "class" that inherits from Base "class".
> 
> 1. How to declare Base class.
> 
> a. Declare Base class namespace:
> 
> <xsl:stylesheet [...] xmlns:Base="Base">
> 
> b. Declare Base class methods and virtual table:
> 
> <Base:class>
>   <Base:Method1 method="Method1"/>
>   <Base:Method2 method="Method2"/>
> </ Base:class>
> 
> <xsl:variable name="Base:class" select="document('')// Base:class"/>
> <xsl:variable name="Base:vtable" select="$Base:class/*"/>
> 
> The variable "$Base:vtable" is a virtual table for Base class.
> 
> 2. How to declare Base class method handlers.
> 
> <xsl:template match="Base:Method1">
>   <xsl:param name="this"/>
>   <xsl:param name="vtable"/>
>   <!-- code is here -->
> </xsl:template>
> 
> Each method should declare "vtable" parameter. The "this" parameter is
> supposed to be used as a node reference to real XML data.
> 
> 3. How to declare Child class
> 
> a. Declare Base and Child class namespaces:
> 
> <xsl:stylesheet [...] xmlns:Child="Child" xmlns:Base="Base">
> 
> b. Use <xsl:include> if necessary:
> 
> <xsl:include href="Base.xsl"/>
> 
> c. Declare Child class methods and inherit virtual methods from Base class:
> 
> <Child:class>
>   <Child:Method1 method="Method1"/>
>   <Child:NewMethod3 method="NewMethod3"/>
> </Child:class>
> 
> <xsl:variable name="Child:class" select="document('')//Child:class"/>
> <xsl:variable name="Child:BaseMethods"
> select="$Base:vtable[not(@method=$Child:class/*/@method)]"/>
> 
> <xsl:variable name="Child:vtable" select="$Child:class/* |
> $Child:BaseMethods"/>
> 
> Variable "$Child:BaseMethods" contains only those methods that are declared
> in the Base class but not declared in the Child class.
> 
> So, each class declares its own virtual table that is accessible by
> "${ClassNamespace}:vtable" variable. In this example virtual tables are:
> "$Base:vtable" and "$Child:vtable".
> 
> 4. How to make virtual method call:
> 
> <xsl:template match="Base:Method1">
>   <xsl:param name="this"/>
>   <xsl:param name="vtable"/>
> 
>   <xsl:apply-templates select="$vtable[local-name()='Method2']">
>      <xsl:with-param name="this" select="$this"/>
>      <xsl:with-param name="vtable" select="$vtable"/>
>      <!-- Other Method2 parameters -->
>   </xsl:apply-templates>
> </xsl:template>
> 
> 5. How to call base class methods from child classes:
> 
> <xsl:template match="Child:Method1"> <!-- declaration of Child:Method1
> handler -->
>   <xsl:param name="this"/>
>   <xsl:param name="vtable"/>
>   <doSomethingNew>
>      <xsl:apply-templates select="$Base:vtable[local-name()='Method1']">
>         <xsl:with-param name="this" select="$this"/>
>         <xsl:with-param name="vtable" select="$vtable"/>
>      </xsl:apply-templates>
>   </doSomethingNew>
> </xsl:template>
> 
> It means that in order to call base class methods you need to select method
> from concrete class virtual table. But it is still necessary to pass source
> $vtable parameter to it.
> 
> 6. How to define special handler for abstract methods:
> 
> It is easy to force overriding of all abstract methods by declaring the
> following template in corresponding class (in this case it is Base class):
> 
> <xsl:template match="*[namespace-uri()='Base']" priority="-1">
>   <xsl:message terminate="yes">
>      Abstract method "Base:<xsl:value-of select="local-name()"/>" was
> called
>   </xsl:message>
> </xsl:template>
> 
> Hope somebody will enjoy this approach while developing with XSL.
> 
> Best Regards,
> Andrey Basko

Current Thread