Re: [xsl] Advise on xsl usage producing very complex html

Subject: Re: [xsl] Advise on xsl usage producing very complex html
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 31 Jan 2001 17:31:33 +0000
Hi Viewga,

> So I want to use some kind of ColdFusion like
> templates, hiding design tricks from xsl providing functional
> implementation. But thats itself a tricky way cause if in CF one can
> write a template which will be used as
> <cf_mytemplate param1="val1">content</cf_mytemplate>
> in xsl it will be
> <xsl:call-template name="mytemplate">
> <xsl:with-param name="param1" select="val1"/>
> <xsl:with-param name="content">Content</xsl:with-param>
> </xsl:call-template>
> which is far longer and less readable if compared.

If it's really simple then you could use a 'literal result element as
stylesheet'-type stylesheet, and just include the relevant
xsl:value-ofs as required, scattered throughout the HTML.  But it
looks as though you're getting into more complicated things here,
which mean that you have to use template.

Given that, it's probably best to have the designers design their HTML
template in whatever they like using, however they want to, and insert
elements in a different namespace to indicate where they want
information from the source XML to be inserted into the template. So
for example, get them to write (or adapt what they write to contain):

<table width, height, bgcolor, cellspacing, cellpadding><tr  valign, bgcolor><td>
<table width, height, bgcolor, cellspacing, cellpadding><tr valign, bgcolor><td>
<table width, height, bgcolor,cellspacing,cellpadding>
<tr valign, bgcolor><td valign, bgcolor,align>
   <!-- make up your own vocabulary for indicating what you want to
        insert and where -->
   <foo:insert>uid</foo:insert>
</td></tr></table></td></tr></table>

You can store this in a separate file, so you have three files:
(a) source.xml - the XML with the source information in it
(b) template.xhtml - the HTML from the designers, with indications
    where information from the source XML needs to go
(c) style.xsl - the stylesheet that takes the template and the source
    and bungs them together

It doesn't matter which of the source or template is used as the
primary input - you should treat them basically as equals, storing the
root node of each in a global variable:

<xsl:variable name="source" select="/" />
<xsl:variable name="template" select="document('template.xhtml')" />
    
In your stylesheet, you should basically use a 'push' technique with
the template (let it drive the processing) and a 'pull' technique with
the source XML (let the processing drive what information is pulled
out of it).  The first thing you need to do is apply templates to the
template node tree rather than the source node tree:

<xsl:template match="/">
   <xsl:apply-templates select="$template/html" />
</xsl:template>

By default, copy everything you find in the template node tree:

<xsl:template match="node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
   </xsl:copy>
</xsl:template>

Then you should have templates for the instructions that you've used,
to override this default template, and to insert stuff from the source
XML instead.  For example:

<xsl:template match="foo:insert[. = 'uid']">
   <xsl:value-of select="$source/root/uid" />
</xsl:template>

Of course that's a simple example: you could equally have something
in the HTML template file that were structured like the ColdFusion
elements, that you then interpreted within the stylesheet to get the
behaviour you're after:

<xsl:template match="cf_mytemplate">
   <xsl:call-template name="mytemplate">
      <xsl:with-param name="param1" select="@param1" />
      <xsl:with-param name="content" select="." />
   </xsl:call-template>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



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


Current Thread