AxKit.org [logo curtesy of http://xml.com]
--sep--
Start Navigation
About AxKit
Index
xml.apache.org
Features
Live Sites
Installation
Documentation
Daily Churn
Getting AxKit
License
Download
Mailing List
Contribute
CVS
Support
Bugs
End Navigation
Prev Top Next

Using XPathScript to Write XSP TagLibs

XSP is an alternative server side XML programming API. It is not a stylesheet system though - the XSP page is executed directly without a stylesheet. XSP was originally incorporated into the Cocoon application framework, and AxKit included XSP capabilities because it's a very interesting and useful tool.

One of the interesting things about XSP is the ability to write taglibs using some form of stylesheet transformation language. A taglib is a separate sheet of tags that have special meaning to your code. They can execute external functions or simply be used in a similar way to external parsed entities. Here's the classic example of a usage of a taglib from the Cocoon documentation (slightly modified from the original):

<xsp:page
language="Perl"
xmlns:xsp="http://www.apache.org/1999/XSP/Core"
xmlns:example="http://www.plenix.com/DTD/XSP/Example"
>
<page title="Time of Day">
<p>
  To the best of my knowledge, it's now
  <!-- Substitute time of day here -->
  <example:time-of-day format="%y/%m/%d %r"/>
</p>
</page>
</xsp:page>

Here the <example:time-of-day> tag gets converted at run time to the current time using the strftime format specified in the format attribute.

A taglib implementation is a stylesheet that is evaluated against this file prior to passing it to the XSP processor. The stylesheet converts the tags that it recognises into pure XSP code (see http://xml.apache.org/cocoon/xsp.html for more information on XSP). While this seems a rather redundant feature, it allows even further separation between code and design. Designers can just introduce these special tags, without worrying about the logic behind them.

The Cocoon recommendation is to write taglibs using XSLT. This works well, but the code often looks confusing. My recommendation for AxKit is to use XPathScript. Here's our implementation of the time-of-day tag using XPathScript:

<%
$t->{'xsp:page'}{prechildren} = <<EOXML;
<xsp:structure>
	<xsp:include>POSIX</xsp:include>
</xsp:structure>
EOXML

$t->{'example:time-of-day'}{testcode} = sub {
        my ($node, $t) = @_;
        $t->{pre} = 
'<xsp:expr>
	POSIX::strftime("' . findvalue('@format', $node) . '", localtime)
</xsp:expr>';
        return 1;
    };
%>
<%= apply_templates() %>
This is a rather trivial example of a taglib, but hopefully it introduces the possibilities of further extending your tag library.

In order to enable this tag library, we simply make the taglib stylesheet the first in our stylesheet cascade:

<?xml version="1.0"?>
<?xml-stylesheet type="application/x-xpathscript" href="example.taglib"?>
<?xml-stylesheet type="application/x-xsp" href="."?>
<?xml-stylesheet type="text/xsl" href="example.xsl"?>
<xsp:page
language="Perl"
xmlns:xsp="http://www.apache.org/1999/XSP/Core"
xmlns:example="http://www.plenix.com/DTD/XSP/Example"
>
<page title="Time of Day">
  <p>
    To the best of my knowledge, it's now
    <!-- Substitute time of day here -->
    <example:time-of-day format="%y/%m/%d %r"/>
  </p>
</page>
</xsp:page>
Note that the XSP script is executed using the stylesheet processing instruction, with a stylesheet of ".". This stylesheet could be anything in the case of XSP, since there is actually no stylesheet associated with it, and the "." is merely a convention.

For comparison, here's the equivalent XSLT based taglib:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
  xmlns:xsp="http://www.apache.org/1999/XSP/Core"
  xmlns:example="http://www.plenix.com/DTD/XSP/Example"
>
  <xsl:template match="xsp:page">
    <xsp:page>
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
      </xsl:copy>
      <xsp:structure>
        <xsp:include>POSIX</xsp:include>
      </xsp:structure>
      <xsl:apply-templates/>
    </xsp:page>
  </xsl:template>

  <xsl:template match="example:time-of-day">
    <xsp:expr>
			POSIX::strftime("<xsl:value-of select="@format"/>", localtime)
    </xsp:expr>
  </xsl:template>

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

</xsl:stylesheet>
Some people may find one version easier to work with than the other, although I personally prefer the simplicity of XPathScript.


Prev Top Next

Printer Friendly
Raw XML