<?xml version="1.0"?>
<article xmlns:pod="http://axkit.org/ns/2000/pod2xml">
    <artheader>
        <title>AxKit - XML Application Server</title>
	<author>
		<firstname>Matt</firstname>
		<surname>Sergeant</surname>
		<affiliation>
			<address><email>matt@sergeant.org</email></address>
		</affiliation>
	</author>
	
	<copyright>
		<year>2000</year>
		<holder role="mailto:matt@sergeant.org">AxKit.com Ltd</holder>
	</copyright>

	<abstract>
		<para>This document is a guide to the ins and outs of using AxKit</para>
	</abstract>

    </artheader>
    
<sect1>
<title>AxKit - XML Application Server</title>
<para>
AxKit is an XML Application Server, written using the mod_perl
framework. At it's core, AxKit provides the developer with many ways
to setup server side XML transformations. In reality, this allows you
to rapidly develop sites that use XML, allowing delivery of the same
content in different formats, and also to allow you to change the
layout of your site very easily, due to the forced separation of
content from presentation.
</para>
<para>
This appendix gives an overview of the ways you can put AxKit to use
on your mod_perl enabled server. It is not a complete description of
all the capabilities of AxKit. For more detailed information, please
take a look at the documentation provided on the AxKit web site at
http://axkit.org/. Commercial support and consultancy services for
AxKit are available at http://axkit.com/.
</para>
<para>
The key benefit to using XML application servers is their support for
W3C recommendations. There are many templating technologies available
in the Perl world, but only XSLT is a W3C recommendation [F]1[/F] . Because
XML is a de-facto standard,it breaks down the barriers between people
using Java or Perl or Python, because ultimately we are all working
with the same data formats. Plus we also have the advantage that many
tools are built, or being built, for writing XML and XSLT, allowing
designers and developers to use the tools of their choice for
authoring their content. Other benefits include a well designed
scaleable architecture, flexible site layout options, and simple to
build dynamic web applications.
</para>
</sect1>
<sect1>
<title>Installing and Configuring</title>
<para>
While we aim to make the AxKit installation as simple as possible,
there are many configuration options that allow you to customize your
installation. So in this section we aim to get you started as quickly
as possible. This section assumes you already have mod_perl and Apache
installed and working. See the Chapter X if this is not the case. This
section does not cover installing AxKit on Win32 systems, for which
there is an ActiveState package at &lt;URL&gt;.
</para>
<para>
First download the latest version of AxKit, which you can get either
from your local CPAN archive, or from the AxKit download directory at
http://axkit.org/. Then type the following:
</para>
<programlisting>
% gunzip -c AxKit-x.xx.tar.gz | tar xvf -
% cd AxKit-x.xx.tar.gz
% perl Makefile.PL
% make
% su
% make test install
</programlisting>
<para>
If perl Makefile.PL warns about missing modules, notably XML::XPath,
make a note of the missing modules and install them from the CPAN.
AxKit will run without the missing modules, but without XML::XPath it
will be impossible to run the examples below [F]2[/F].
</para>
<para>
Now we need to add some simple options to the very end of our
httpd.conf file:
</para>
<programlisting>
PerlModule AxKit
AddHandler axkit .xml
AddHandler axkit .xsp
AddHandler axkit .dkb
AxDebugLevel 10
PerlSetVar AxXPSInterpolate 1
</programlisting>
<para>
Note that
the first line: PerlModule AxKit must occur in your httpd.conf outside
of any runtime configuration blocks, otherwise Apache cannot see the
AxKit configuration directives and you will get errors when you try
and start the httpd.
</para>
<para>
Now if you have XML::XPath installed (try perl -MXML::XPath -e0 on the
command line to check), (re)start your Apache server. You are now
ready to begin publishing transformed XML with AxKit!
</para>
</sect1>
<sect1>
<title>Your First AxKit Page</title>
<para>
Now we're going to see how AxKit works by transforming an XML file
containing data about Camelids (note the dubious Perl reference) into
HTML.
</para>
<para>
First you will need a sample XML file. Open the text editor of your
choice and type the following:
</para>
<programlisting>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;dromedaries&gt;
  &lt;species name=&quot;Camel&quot;&gt;
    &lt;humps&gt;1 or 2&lt;/humps&gt;
    &lt;disposition&gt;Cranky&lt;/disposition&gt;
  &lt;/species&gt;
  &lt;species name=&quot;Llama&quot;&gt;
    &lt;humps&gt;1&lt;/humps&gt;
    &lt;disposition&gt;Aloof&lt;/disposition&gt;
  &lt;/species&gt;
  &lt;species name=&quot;Alpaca&quot;&gt;
    &lt;humps&gt;(see Llama)&lt;/humps&gt;
    &lt;disposition&gt;Friendly&lt;/disposition&gt;
  &lt;/species&gt;
&lt;/dromedaries&gt;
</programlisting>
<para>
Save this file in your web server root (normally
/path/to/apache/htdocs/) as test.xml.
</para>
<para>
Now we need a stylesheet to transform that to HTML. For this first
example we are going to introduce XPathScript, an XML transformation
language specific to AxKit. Later we will give a brief introduction to
XSLT.
</para>
<para>
Create a new file and type in:
</para>
<programlisting>
&lt;%
$t-&gt;{'humps'}{pre} = &quot;&lt;td&gt;&quot;;
$t-&gt;{'humps'}{post} = &quot;&lt;/td&gt;&quot;;
$t-&gt;{'disposition'}{pre} = &quot;&lt;td&gt;&quot;;
$t-&gt;{'disposition'}{post} = &quot;&lt;/td&gt;&quot;;
$t-&gt;{'species'}{pre} = &quot;&lt;tr&gt;&lt;td&gt;{\@name}&lt;/td&gt;&quot;;
$t-&gt;{'species'}{post} = &quot;&lt;/tr&gt;&quot;;
%&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Know Your Dromedaries&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;table border=&quot;1&quot;&gt;
    &lt;tr&gt;&lt;th&gt;Species&lt;/th&gt;
        &lt;th&gt;No. of Humps&lt;/th&gt;
        &lt;th&gt;Disposition&lt;/th&gt;&lt;/tr&gt;
    &lt;%= apply_templates('/dromedaries/species') %&gt;
  &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>
<para>
Save this file as test.xps.
</para>
<para>
Now to get the original file test.xml to be transformed on the server
with text.xps we need to somehow associate that file with the
stylesheet. Under AxKit there are a number of ways to do that with
varying flexibility. The simplest way is to edit your test.xml file,
and immediately after the &lt;?xml version=&quot;1.0&quot;?&gt; declaration, add the
following:
</para>
<programlisting>
&lt;?xml-stylesheet href=&quot;test.xps&quot;
                 type=&quot;application/x-xpathscript&quot;?&gt;
</programlisting>
<para>
Now assuming the files are both in the same directory under your httpd
document root, you should be able to do a request for text.xml and see
in your browser server side transformed XML. Now try changing the
source XML file, and watch AxKit detect the change next time you load
the file in the browser.
</para>

<title>If things go wrong...</title>
<para>
If you don't see HTML in your browser, but instead get the source XML
in your browser (in Internet Explorer you will see a tree based
representation of the XML, and in Mozilla or Netscape you will see all
the text in the document joined together), then you will need to check
your error log. AxKit sends out varying amounts of debug information
depending on the value of AxDebugLevel (which we set to the maximum
value of 10). If you can't decipher the contents of the error log,
contact the AxKit User's mailing list at axkit-users@axkit.org with
details of your problem.
</para>


<title>How does it work?</title>
<para>
The stylesheet above specifies how the various tags work. The ASP &lt;%
%&gt; syntax delimits Perl code from HTML. You can execute any code
within the stylesheet, however here we are making use of the special
XPathScript $t hash ref. This specifies the names of tags, and how
they should be output to the browser. There are several options for
the second level of the hash, and here we see two of those options:
pre and post. This specifies quite simply, what appears before the
tag, and what appears after it. These values in $t only take affect
when we call the apply_templates() function, which iterates over the
nodes in the XML, executing the matching values in $t.
</para>


<title>XPath</title>
<para>
One of the key specifications being used in XML technologies is XPath.
This is a little language used within other languages for selecting
nodes within an XML document. The initial appearance is similar to
that of Unix directory paths. In the above example we can see the
XPath /dromedaries/species, which starts at the root of the document
and finds first the dromedaries root element, then the species
children of the dromedaries element. Note that unlike Unix directory
paths, XPaths can match multiple nodes, so in the case above, we
select all of the species elements in the document.
</para>
<para>
Documenting all of XPath here would take up many pages. The grammar
for XPath allows many constructs of a full programming language, such
as functions, string literals, and boolean expressions, but it is
important to know that the syntax we are using to find nodes in our
XML document is not just something invented for AxKit!
</para>

</sect1>
<sect1>
<title>Dynamic Content</title>
<para>
AxKit has a flexible tool for creating XML from various data sources
such as relational databases, cookies, and form parameters, called
eXtensible Server Pages, or XSP. This technology was originally
invented by they Apache Cocoon team, and we share their syntax [F]3[/F].
This allows easier migration of projects to and from Cocoon.
</para>
<para>
XSP is an XML based syntax that uses namespaces to provide
extensibility. In many ways this is like the Cold Fusion model, of
using tags to provide dynamic functionality. One of the advantages of
using XSP is that it is impossible to generate invalid XML, which
makes it ideal for use in an XML framework like AxKit.
</para>
<para>
The XSP framework allows you to add in extra tags into your XML to
provide custom functionality. These extra tags are called taglibs. By
using taglibs, rather than embedding Perl code in your XSP page, you
can further build on AxKit's separation of content from presentation,
by separating out logic too. There are several taglibs that are
available for AxKit's XSP engine already on CPAN.
</para>

<title>Handling Form Parameters</title>
<para>
The AxKit::XSP::Param taglib allows you to easily read form and
querystring parameters within an XSP page. The following example shows
how a page can submit back to itself. To allow this to work, the
following needs to be added to your httpd.conf:
</para>
<programlisting>
AxAddXSPTaglib AxKit::XSP::Param
</programlisting>
<para>
Then the XSP page is:
</para>
<programlisting>
&lt;xsp:page
 xmlns:xsp=&quot;http://apache.org/xsp/core/v1&quot;
 xmlns:param=&quot;http://axkit.org/NS/xsp/param/v1&quot;
 language=&quot;Perl&quot;
&gt;
&lt;page&gt;
  &lt;xsp:logic&gt;
  if (&lt;param:name/&gt;) {
    &lt;xsp:content&gt;
     Your name is: &lt;param:name/&gt;
    &lt;/xsp:content&gt;
  }
  else {
    &lt;xsp:content&gt;
      &lt;form&gt;
        Enter your name: &lt;input type=&quot;text&quot; name=&quot;name&quot; /&gt;
        &lt;input type=&quot;submit&quot;/&gt;
      &lt;/form&gt;
    &lt;/xsp:content&gt;
  }
  &lt;/xsp:logic&gt;
&lt;/page&gt;
&lt;/xsp:page&gt;
</programlisting>
<para>
The most significant factor about the above is how we freely mix XML
tags with our Perl code, and the XSP processor figures out the right
thing to do depending on context. There is a consequence of this, in
that the XSP page itself must be valid XML, so the following would
generate an error:
</para>
<programlisting>
&lt;xsp:logic&gt;
my $page = &lt;param:page/&gt;;
if ($page &lt; 3) { # ERROR: less-than is a reserved character in XML
 ...
}
&lt;/xsp:logic&gt;
</programlisting>
<para>
In order to get around this restriction, there are a number of ways we
can code this in XML. The simplest is just to reverse the expression
to if (3 &gt; $page), because the greater-than sign is valid within an
XML text section. Another way is to encode the less-than sign as &amp;lt;,
which will be familiar to HTML authors.
</para>
<para>
The other thing to notice is the &lt;xsp:logic&gt; and &lt;xsp:content&gt; tags.
The former defines a section of Perl code, while the latter allows you
to go back to processing the contents as XML output. It is also worth
noting that the &lt;xsp:content&gt; tag is not always needed. Because the
XSP engine inherently understands XML, you can omit the &lt;xsp:content&gt;
tag when the immediate child would be an element, rather than text.
Two examples would be:
</para>
<programlisting>
&lt;xsp:logic&gt;
if (&lt;param:name/&gt;) {
  # xsp:content needed
  &lt;xsp:content&gt;
  Your name is: &lt;param:name/&gt;
  &lt;/xsp:content&gt;
}
&lt;/xsp:logic&gt;
</programlisting>
<para>
versus the case when there is a surrounding non-XSP tag:
</para>
<programlisting>
&lt;xsp:logic&gt;
if (&lt;param:name/&gt;) {
  # no xsp:content tag needed
  &lt;p&gt;Your name is: &lt;param:name/&gt;&lt;/p&gt;
}
&lt;/xsp:logic&gt;
</programlisting>
<para>
Note that the initial example, when processed only by the XSP engine,
will output the following XML:
</para>
<programlisting>
&lt;page&gt;
  &lt;form&gt;
    Enter your name: &lt;input type=&quot;text&quot; name=&quot;name&quot; /&gt;
    &lt;input type=&quot;submit&quot;/&gt;
  &lt;/form&gt;
&lt;/page&gt;
</programlisting>
<para>
This needs processed with XSLT or XPathScript to be reasonably
viewable in a browser, however the point is that you can re-use the
above page as either HTML or WML just by applying different
stylesheets.
</para>


<title>Handling Cookies</title>
<para>
AxKit::XSP::Cookie is a taglib interface to Apache::Cookie (part of
the libapreq package). The following example demonstrates both
retrieving and setting a cookie from within XSP. In order for this to
run, the following option needs to be added to your httpd.conf:
</para>
<programlisting>
AxAddXSPTaglib AxKit::XSP::Cookie
</programlisting>
<para>
And the XSP page is:
</para>
<programlisting>
&lt;xsp:page
 xmlns:xsp=&quot;http://apache.org/xsp/core/v1&quot;
 xmlns:cookie=&quot;http://axkit.org/NS/xsp/cookie/v1&quot;
 language=&quot;Perl&quot;
&gt;
&lt;page&gt;
  &lt;xsp:logic&gt;
  my $value;
  if ($value = &lt;cookie:fetch name=&quot;count&quot;/&gt;) {
    $value++;
  }
  else {
    $value = 1;
  }
  &lt;/xsp:logic&gt;
  &lt;cookie:create name=&quot;count&quot;&gt;
    &lt;cookie:value&gt;&lt;xsp:expr&gt;$value&lt;/xsp:expr&gt;&lt;/cookie:value&gt;
  &lt;/cookie:create&gt;
  &lt;p&gt;Cookie value: &lt;xsp:expr&gt;$value&lt;/xsp:expr&gt;&lt;/p&gt;
&lt;/page&gt;
&lt;/xsp:page&gt;
</programlisting>
<para>
This page introduces the concept of XSP expressions, using the
&lt;xsp:expr&gt; tag. In XSP, everything that returns a value is an
expression of some sort. In both of the above examples we have used a
taglib tag within a Perl if() statement. These tags have both been
expressions, even though they don't use the &lt;xsp:expr&gt; syntax. In XSP,
everything understands its context, and tries to do the right thing.
This way, the following three examples would work as expected:
</para>
<programlisting>
&lt;cookie:value&gt;3&lt;/cookie:value&gt;

&lt;cookie:value&gt;&lt;xsp:expr&gt;2 + 1&lt;/xsp:expr&gt;&lt;/cookie:value&gt;

&lt;cookie:value&gt;&lt;param:cookie_value/&gt;&lt;/cookie:value&gt;
</programlisting>


<para>
We see this as an extension of how Perl works - the idea of &quot;Do What I
Mean&quot;, or DWIM.
</para>


<title>Sending Email</title>
<para>
With the AxKit::XSP::Sendmail taglib it is very simple to send email
from an XSP page. This taglib combines email address verification
using the Email::Valid module, along with email sending using the
Mail::Sendmail module (which will interface either to an SMTP server,
or direct to the sendmail executable). Again, to allow usage of this
taglib, the following line must be added to httpd.conf:
</para>
<programlisting>
AxAddXSPTaglib AxKit::XSP::Sendmail
</programlisting>
<para>
Then sending email from XSP is as simple as:
</para>
<programlisting>
&lt;xsp:page
 xmlns:xsp=&quot;http://apache.org/xsp/core/v1&quot;
 xmlns:param=&quot;http://axkit.org/NS/xsp/param/v1&quot;
 xmlns:mail=&quot;http://axkit.org/NS/xsp/sendmail/v1&quot;
 language=&quot;Perl&quot;
&gt;
&lt;page&gt;
  &lt;xsp:logic&gt;
  if (!&lt;param:email/&gt;) {
    &lt;p&gt;You forgot to supply an email address!&lt;/p&gt;
  }
  else {
    my $to;
    if (&lt;param:subopt/&gt; eq &quot;sub&quot;) {
      $to = &quot;axkit-users-subscribe@axkit.org&quot;;
    }
    elsif (&lt;param:subopt/&gt; eq &quot;unsub&quot;) {
      $to = &quot;axkit-users-unsubscribe@axkit.org&quot;;
    }
    &lt;mail:send-mail&gt;
     &lt;mail:from&gt;&lt;param:user_email/&gt;&lt;/mail:from&gt;
     &lt;mail:to&gt;&lt;xsp:expr&gt;$to&lt;/xsp:expr&gt;&lt;/mail:to&gt;
     &lt;mail:body&gt;
      Subscribe or Unsubscribe &lt;param:user_email/&gt;
     &lt;/mail:body&gt;
    &lt;/mail:send-mail&gt;
    &lt;p&gt;(un)subscription request sent&lt;/p&gt;
  }
  &lt;/xsp:logic&gt;
&lt;/page&gt;
&lt;/xsp:page&gt;
</programlisting>
<para>
The only thing missing here is some sort of error handling. When the
sendmail taglib detects an error (either in an email address, or in
sending the email), it throws an exception.
</para>


<title>Handling Exceptions</title>
<para>
The exception taglib, AxKit::XSP::Exception, is used to catch
exceptions. The syntax is very simple, rather than allowing different
types of exceptions, it is currently a very simple try/catch block. To
use the exceptions taglib, the following has to be added to
httpd.conf:
</para>
<programlisting>
AxAddXSPTaglib AxKit::XSP::Exception
</programlisting>
<para>
Then we can implement form validation using exceptions:
</para>
<programlisting>
&lt;xsp:page
 xmlns:xsp=&quot;http://apache.org/xsp/core/v1&quot;
 xmlns:param=&quot;http://axkit.org/NS/xsp/param/v1&quot;
 xmlns:except=&quot;http://axkit.org/NS/xsp/exception/v1&quot;
 language=&quot;Perl&quot;
&gt;
&lt;page&gt;
 # form validation:
 &lt;except:try&gt;
  &lt;xsp:logic&gt;
  if ((&lt;param:number/&gt; &gt; 10) || (0 &gt; &lt;param:number/&gt;)) {
    die &quot;Number must be between 0 and 10&quot;;
  }
  if (!&lt;param:name/&gt;) {
    die &quot;You must supply a name&quot;;
  }
  # Now do something with the params
  &lt;/xsp:logic&gt;
  &lt;p&gt;Values saved successfully!&lt;/p&gt;
  &lt;except:catch&gt;
   &lt;p&gt;Sorry, the values you entered were
      incorrect: &lt;except:message/&gt;&lt;/p&gt;
  &lt;/except:catch&gt;
 &lt;/except:try&gt;
&lt;/page&gt;
</programlisting>
<para>
The exact same try/catch (and message) tags can be used for sendmail,
and for ESQL (see below).
</para>


<title>Utilities Taglib</title>
<para>
The AxKit::XSP::Util taglib includes some utility methods for
including XML, from the filesystem, from a URI, or as the return value
from an expression (normally an expression would be rendered as plain
text, and so a &quot;&lt;&quot; character would be encoded as &quot;&amp;lt;&quot;). The AxKit
Util taglib is a direct copy of the Cocoon Util taglib, and as such
uses the same namespace as the Cocoon Util taglib:
http://apache.org/xsp/util/v1.
</para>


<title>Executing SQL</title>
<para>
Perhaps the most interesting taglib of all is the ESQL taglib, which
allows you to execute SQL queries against a DBI compatible database,
and provides access to the column return values as strings, scalars,
numbers, dates, or even as XML (the latter uses the Util taglib, which
must be installed in order to be able to use the ESQL taglib). Like
the sendmail taglib, the ESQL taglib throws exceptions when an error
occurs. One point of interest about the ESQL taglib is that it is a
direct copy of the Cocoon ESQL taglib [F]4[/F], again helping you to port
projects to or from Cocoon. As with all the other taglibs, ESQL
requires the addition of the following to your httpd.conf:
</para>
<programlisting>
AxAddXSPTaglib AxKit::XSP::ESQL
</programlisting>
<para>
An example ESQL usage which reads data from an address book table is
below. This page demonstrates how it is possible to re-use the same
code for both our list of addresses, and viewing a single address in
detail.
</para>
<programlisting>
&lt;xsp:page
 language=&quot;Perl&quot;
 xmlns:xsp=&quot;http://apache.org/xsp/core/v1&quot;
 xmlns:esql=&quot;http://apache.org/xsp/SQL/v2&quot;
 xmlns:except=&quot;http://axkit.org/NS/xsp/exception/v1&quot;
 xmlns:param=&quot;http://axkit.org/NS/xsp/param/v1&quot;
 indent-result=&quot;no&quot;
&gt;
&lt;addresses&gt;
 &lt;esql:connection&gt;
  &lt;esql:driver&gt;Pg&lt;/esql:driver&gt;
  &lt;esql:dburl&gt;dbname=phonebook&lt;/esql:dburl&gt;
  &lt;esql:username&gt;postgres&lt;/esql:username&gt;
  &lt;esql:password&gt;&lt;/esql:password&gt;
  &lt;except:try&gt;
  &lt;esql:execute-query&gt;
   &lt;xsp:logic&gt;
   if (&lt;param:address_id/&gt;) {
    &lt;esql:query&gt;
     SELECT * FROM address WHERE id =
     &lt;esql:parameter&gt;&lt;param:address_id/&gt;&lt;/esql:parameter&gt;
    &lt;/esql:query&gt;
   }
   else {
    &lt;esql:query&gt;
     SELECT * FROM address
    &lt;/esql:query&gt;
   }
   &lt;/xsp:logic&gt;
   &lt;esql:results&gt;
    &lt;esql:row-results&gt;
     &lt;address&gt;
      &lt;esql:get-columns/&gt;
     &lt;/address&gt;
    &lt;/esql:row-results&gt;
   &lt;/esql:results&gt;
  &lt;/esql:execute-query&gt;

&lt;except:catch&gt;
 Error Occured: &lt;except:message/&gt;
&lt;/except:catch&gt;
&lt;/except:try&gt;
     &lt;/esql:connection&gt;
    &lt;/addresses&gt;
    &lt;/xsp:page&gt;
</programlisting>

<para>
The result of running the above through the XSP processor is:
</para>
<programlisting>
&lt;addresses&gt;
 &lt;address&gt;
  &lt;id&gt;2&lt;/id&gt;
  &lt;last_name&gt;Sergeant&lt;/last_name&gt;
  &lt;first_name&gt;Matt&lt;/first_name&gt;
  &lt;title&gt;Mr&lt;/title&gt;
  &lt;company&gt;AxKit.com Ltd&lt;/company&gt;
  &lt;email&gt;matt@axkit.com&lt;/email&gt;
  &lt;classification_id&gt;1&lt;/classification_id&gt;
 &lt;/address&gt;
&lt;/addresses&gt;
</programlisting>

</sect1>
<sect1>
<title>More XPathScript Details</title>
<para>
XPathScript aims to provide the power and flexibility of XSLT as an
XML transformation language, without the restriction of XSLT's XML
based syntax. Unlike XSLT, XPathScript only outputs plain text (XSLT
has special modes for outputting in text, XML and HTML). This has
advantages in being a lot easier to learn than XSLT for people coming
from a Perl background, however XPathScript is not a W3C specification
(although XPath, which XPathScript uses, is a W3C recommendation).
</para>
<para>
XPathScript follows the basic ASP syntax for introducing code, and
outputting code to the browser; use &lt;% %&gt; to introduce Perl code, and
&lt;%= %&gt; to output a value.
</para>

<title>The XPathScript API</title>
<para>
Along with the code delimiters XPathScript provides stylesheet
developers with a full API for accessing and transforming the source
XML file. This API can be used in conjunction with the delimiters
above to provide a stylesheet language that is as powerful as XSLT,
and yet provides all the features of a full programming language (in
this case, Perl, but I'm certain that other implementations such as
Python or Java would be possible).
</para>

<title>Extracting Values</title>
<para>
A simple example to get us started, is to use the API to bring in the
title from a docbook article. A docbook article title looks like this:
</para>
<programlisting>
&lt;article&gt;
 &lt;artheader&gt;
  &lt;title&gt;XPathScript - A Viable Alternative to XSLT?&lt;/title&gt;
  ...
</programlisting>
<para>
The XPath expression to retrieve the text in the title element is:
</para>
<programlisting>
/article/artheader/title/text()
</programlisting>
<para>
Putting this all together to make this text into the HTML title we get
the following XPathScript stylesheet:
</para>
<programlisting>
&lt;html&gt;
&lt;head&gt;
 &lt;title&gt;&lt;%= findvalue(&quot;/article/artheader/title&quot;) %&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  This was a DocBook Article. 
  We're only extracting the title for now!
&lt;p&gt;
The title was: &lt;%= findvalue(&quot;/article/artheader/title&quot;) %&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting>
<para>
Again we see the XPath syntax being used to find the nodes in the
document, along with the function findvalue(). Similarly a list of
nodes can be extracted (and thus looped over) using the findnodes()
function:
</para>
<programlisting>
...
&lt;%
for my $sect1 (findnodes(&quot;/article/sect1&quot;)) {
  print $sect1-&gt;findvalue(&quot;title&quot;), &quot;&lt;br&gt;\n&quot;;
  for my $sect2 ($sect1-&gt;findnodes(&quot;sect2&quot;)) {
    print &quot; + &quot;, $sect2-&gt;findvalue(&quot;title&quot;), &quot;&lt;br&gt;\n&quot;;
    for my $sect3 ($sect2-&gt;findnodes(&quot;sect3&quot;)) {
      print &quot; + + &quot;, $sect3-&gt;findvalue(&quot;title&quot;), &quot;&lt;br&gt;\n&quot;;
    }
  }
}
%&gt;
...
</programlisting>
<para>
Here we see how we can apply the find* functions to individual nodes
as methods, which makes the node the context node to search from, so
$node-&gt;findnodes(&quot;title&quot;) finds &lt;title&gt; child nodes of $node.
</para>


<title>Declarative Templates</title>
<para>
We have already seen declarative templates in our &quot;First AxKit Page&quot;
above. The $t hash is the key to declarative templates. The
apply_templates() function iterates over the nodes of your XML file,
applying the templates defined in the $t hash reference as it meets
matching tags. This is the most important feature of XpathScript,
because it allows you to define the appearance for individual tags
without having to do your own iteration logic. We call this
declarative templating.
</para>
<para>
The keys of $t are the names of the elements, including namespace
prefixes where appropriate. When apply_templates() is called,
XPathScript tries to find a member of $t that matches the element
name.
</para>
<para>
The following sub-keys define the transformation:
</para>
<itemizedlist>
<listitem>pre
<para>
the output to occur before the tag.
</para>
</listitem>
<listitem>post
<para>
the output to occur after the tag.
</para>
</listitem>
<listitem>prechildren
<para>
the output to occur before the children of this tag
are written.
</para>
</listitem>
<listitem>postchildren
<para>
the output to occur after the children of this tag are written.
</para>
</listitem>
<listitem>prechild
<para>
output to occur before every child element of this tag.
</para>
</listitem>
<listitem>postchild
<para>
output to occur after every child element of this tag.
</para>
</listitem>
<listitem>showtag
<para>
set to a false value (generally zero) to disable rendering 
of the tag itself.
</para>
</listitem>
<listitem>testcode
<para>
code to execute upon visiting this tag.
</para>
</listitem>
</itemizedlist>
<para>
More details about XPathScript can be found on the AxKit web page, at
http://axkit.org/.
</para>


</sect1>
<sect1>
<title>XSLT</title>
<para>
One of the most important technologies to come out of the W3C is XSLT,
or, Extensible Stylesheet Language Transformations. XSLT provides a
way to transform one type of XML document into another using a
language written entirely in XML. XSLT works by allowing developers to
create one or more template rules that are applied to the various
elements in the source document to produce a second, transformed
document.
</para>
<para>
While the basic concept behind XSLT is quite simple (apply these rules
to the elements that match these conditions), the finer points of
writing good XSLT stylesheets is a huge topic that we could never hope
to cover here. We will instead provide a small example that
illustrates the basic XSLT syntax.
</para>
<para>
First, though, we need to configure AxKit to transform XML documents
using an XSLT processor. For this example, we will assume that you
already have the Gnome XSLT library (libxml2 and libxslt, available at
http://xmlsoft.org/) and its associated Perl modules installed on your
server.
</para>
<programlisting>
AxAddStyleMap text/xsl Apache::AxKit::Language::LibXSLT
</programlisting>
<para>
Adding this line to your httpd.conf file tells AxKit to process all
XML documents with a stylesheet processing instruction whose type is
&quot;text/xsl&quot; with the LibXSLT language module.
</para>

<title>Anatomy Of An XSLT Stylesheet</title>
<para>
All XSLT stylesheets contain the following:
</para>
<itemizedlist>
<listitem><para>
An XML declaration.
</para>
</listitem>
<listitem><para>
An &lt;xsl:stylesheet&gt; element as the document's root element.
</para>
</listitem>
<listitem><para>
A template rule that matches the root-level element of document to
be processed.
</para>
</listitem>
</itemizedlist>
<para>
Consider the following bare-bones stylesheet:
</para>
<programlisting>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;xsl:stylesheet
  xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
  version=&quot;1.0&quot;&gt;
  &lt;xsl:template match=&quot;/&quot;&gt;
    &lt;!-- the content for the output document contained here --&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</programlisting>
<para>
Note that the root template (defined by the match=&quot;/&quot; attribute) will
be called without regard for the contents of the XML document being
processed. As such, this the best place to put the top-level elements
that we want to include in the output of each and every document being
transformed with this stylesheet.
</para>


<title>Template Rules And Recursion</title>
<para>
Let's take our basic stylesheet and extend it to allow us to transform
the following DocBook XML document (which we will call
camelhistory.xml) into HTML:
</para>
<programlisting>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;book&gt;
&lt;title&gt;Camels: An Historical Perspective&lt;/title&gt;
&lt;chapter&gt;
  &lt;title&gt;Chapter One&lt;/title&gt;
  &lt;para&gt;
     It was a dark and &lt;emphasis&gt;stormy&lt;/emphasis&gt; night...
  &lt;/para&gt;
&lt;/chapter&gt;
&lt;/book&gt;
</programlisting>
<para>
First we need to alter the root template of our stylesheet:
</para>
<programlisting>
&lt;xsl:template match=&quot;/&quot;&gt;
  &lt;html&gt;
    &lt;head&gt;&lt;xsl:copy-of select=&quot;/book/title&quot;/&gt;&lt;/head&gt;
    &lt;body&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/body&gt;
  &lt;/html&gt;
&lt;/xsl:template&gt;
</programlisting>
<para>
Here we have created the top-level structure of our output document
and copied over the book's title element into the head element of out
HTML page. The &lt;xsl:apply-templates/&gt; element tells the XSLT processor
to pass the entire contents of the current element (in this case the
&lt;book&gt; element, since it is the root-level element in the source
document) on for further processing.
</para>
<para>
Now we need to create template rules for the other elements in the
document:
</para>
<programlisting>
&lt;xsl:template match=&quot;chapter&quot;&gt;
  &lt;div class=&quot;chapter&quot;&gt;
    &lt;xsl:attribute name=&quot;id&quot;&gt;&lt;xsl:value-of 
    select=&quot;title&quot;/&gt;&lt;/xsl:attribute&gt;
    &lt;xsl:apply-templates/&gt;
  &lt;/div&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;para&quot;&gt;
  &lt;p&gt;&lt;xsl:apply-templates/&gt;&lt;/p&gt;
&lt;/xsl:template&gt;
</programlisting>
<para>
Here we see more examples of recursive processing. The &lt;para&gt; and
&lt;chapter&gt; elements are transformed into &lt;div&gt; and &lt;p&gt; elements and the
contents of those elements are passed along for further processing.
Note also that the XPath expressions used within the template rules
are evaluated in the context of the current element. So, when we
select the value of the title element to create the id attribute for
the div tag, we are really saying &quot;select the value of the title
element that is a child of the current chapter element&quot;.
</para>
<para>
While this sort of recursive processing is extremely powerful, it can
also be quite a performance hit and is only necessary for those cases
where the current element contains other elements that need to be
processed. If we know that a particular element will not contain any
other elements, we need only return that element's text value.
</para>
<programlisting>
&lt;xsl:template match=&quot;emphasis&quot;&gt;
  &lt;em&gt;&lt;xsl:value-of select=&quot;.&quot;/&gt;&lt;/em&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;chapter/title&quot;&gt;
  &lt;h2&gt;&lt;xsl:value-of select=&quot;.&quot;/&gt;&lt;/h2&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;book/title&quot;&gt;
  &lt;h1&gt;&lt;xsl:value-of select=&quot;.&quot;/&gt;&lt;/h1&gt;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</programlisting>
<para>
Look closely at the last two template elements. Both match a &lt;title&gt;
element, but one defines the rule for handling titles whose parent is
a book element, while the other handles the chapter titles. In fact,
any valid XPath expression, XSLT function call, or combination of the
two can be used to define the match rule for a template element.
</para>
<para>
Finally, we need only save our stylesheet as docbook-snippet.xsl. Once
our source document is associated with this stylesheet (see the
section titled Putting It Together in this appendix), if we point our
browser to camelhistory.xml we will get the following output:
</para>
<programlisting>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Camels: An Historical Perspective&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Camels: An Historical Perspective&lt;/h1&gt;
    &lt;div class=&quot;chapter&quot; id=&quot;Chapter One&quot;&gt;
      &lt;h2&gt;Chapter One&lt;/h2&gt;
      &lt;p&gt;
         It was a dark and &lt;em&gt;stormy&lt;/em&gt; night...
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</programlisting>


<title>Learning More</title>
<para>
We have only scratched the surface of how XSLT can be used to
transform XML documents. For more information, see the following
resources:
</para>
<itemizedlist>
<listitem><para>
The XSLT Specification: http://www.w3.org/TR/xslt
</para>
</listitem>
<listitem><para>
Miloslav Nic's XSLT Reference: http://www.zvon.org/xxl/XSLTreference/Output/index.html
</para>
</listitem>
<listitem><para>
Jeni Tennison's XSLT FAQ: http://www.jenitennison.com/xslt/index.html
</para>
</listitem>
</itemizedlist>
<para>
Also note that the complete set of files for the above example XSLT
code is available at http://axkit.org/examples/book-xslt.tar.gz
</para>

</sect1>
<sect1>
<title>Putting Everything Together</title>
<para>
The last key peice to AxKit is how everything is tied together. We
have a clean separation of logic, presentation and content, but we've
only briefly introduced using processing instructions for setting up
the way a file gets processed through the AxKit engine. A generally
better and more scalable way to work is to use the AxKit configuration
directives to specify how to process files through the system.
</para>
<para>
Before introducing the configuration directives in detail, it is worth
looking at how the W3C sees the evolving web of new media types. The
HTML 4.0 specification defined 8 media types:
</para>
<itemizedlist>
<listitem><para>
screen - the default media type, for normal web browsers.
</para>
</listitem>
<listitem><para>
tty - a media type for tty based devices (e.g. the lynx web
browser).
</para>
</listitem>
<listitem><para>
printer
</para>
</listitem>
<listitem><para>
handheld
</para>
</listitem>
<listitem><para>
braille - for braille interpreters
</para>
</listitem>
<listitem><para>
tv - for devices such as Microsoft's WebTV and Sony's Playstation2
that have a TV based browser.
</para>
</listitem>
<listitem><para>
projection - for projectors
</para>
</listitem>
<listitem><para>
aural - for devices that can convert the output to spoken words
</para>
</listitem>
</itemizedlist>
<para>
AxKit allows you to plug in modules that can detect these different
media types, allowing you to deliver the same content in different
ways. For finer grained control, you can use named stylesheets (where
you might have a printable page output to the screen media type, as
seen on many magazine sites such as http://take23.org/ for displaying
multi-page articles).
</para>
<para>
For example, to map all files with extension .dkb to a DocBook
stylesheet, you would use the following directives:
</para>
<programlisting>
&lt;Files *.dkb&gt;
AxAddProcessor text/xsl /stylesheet/docbook.xsl
&lt;/Files&gt;
</programlisting>
<para>
Now if you wanted to display those DocBook files on WebTV as well as
ordinary web browsers, but you wanted to use a different stylesheet
for WebTV, you would use:
</para>
<programlisting>
&lt;Files *.dkb&gt;
  &lt;AxMediaType tv&gt;
    AxAddProcessor text/xsl /stylesheets/docbook_tv.xsl
  &lt;/AxMediaType&gt;
  &lt;AxMediaType screen&gt;
    AxAddProcessor text/xsl /stylesheets/docbook_screen.xsl
  &lt;/AxMediaType&gt;
&lt;/Files&gt;
</programlisting>
<para>
Now let's extend that to chained transformations. Lets say you wanted
to build up a table of contents the same way in both views. One way
you could do it is to modularize the stylesheet. However it's also
possible to chain transformations in AxKit, simply by defining more
than one processor for a particular resource:
</para>
<programlisting>
&lt;Files *.dkb&gt;
  AxAddProcessor text/xsl /stylesheets/docbook_toc.xsl
  &lt;AxMediaType tv&gt;
    AxAddProcessor text/xsl /stylesheets/docbook_tv.xsl
  &lt;/AxMediaType&gt;
  &lt;AxMediaType screen&gt;
    AxAddProcessor text/xsl /stylesheets/docbook_screen.xsl
  &lt;/AxMediaType&gt;
&lt;/Files&gt;
</programlisting>
<para>
Now the TV based browsers will see DocBook first tranformed by
docbook_toc.xsl, then the output of that transformation would be
processed by docbook_tv.xsl.
</para>
<para>
This is exactly how we would build up an application using XSP:
</para>
<programlisting>
&lt;Files *.xsp&gt;
  AxAddProcessor application/x-xsp .
  &lt;AxMediaType tv&gt;
    AxAddProcessor text/xsl /stylesheets/page2tv.xsp
  &lt;/AxMediaType&gt;
  &lt;AxMediaType screen&gt;
    AxAddProcessor text/xsl /stylesheets/page2html.xsp
  &lt;/AxMediaType&gt;
&lt;/Files&gt;
</programlisting>
<para>
This resolves the earlier issue we had where the XSP did not output
HTML - instead it output something entirely different. Now we can see
why - because this way we can build dynamic web applications that work
easily on different devices!
</para>
<para>
There are 4 other config directives similar to AxAddProcessor, which
take an additional parameter specifying a particular way to examine
the file being processed. These each take an additional parameter to
facilitate the match.
</para>
<itemizedlist>
<listitem>AxAddRootProcessor
<para>
takes a root element name to match the first
(root) element in the XML document. For example:
</para>
<programlisting>
AxAddRootProcessor text/xsl article.xsl article
</programlisting>
<para>
Would process all XML files with a root element of &lt;article&gt; with
the article.xsl stylesheet.
</para>
</listitem>
<listitem>AxAddDocTypeProcessor
<para>
processes XML documents with the given XML
public identifier.
</para>
</listitem>
<listitem>AxAddDTDProcessor
<para>
processes all XML documents that use the DTD
given as the third option.
</para>
</listitem>
<listitem>AxAddURIProcessor
<para>
processes all resources at the matching URI
(which is a Perl regexp).
</para>
<para>
This option was added for two reasons - firstly that the
&lt;LocationMatch&gt; directive is not allowed in a .htaccess file, and
secondly that the built in Apache regular expressions are not terribly
powerful (for example they cannot do negative matches).
</para>
</listitem>
</itemizedlist>
<para>
Finally, the &lt;AxStyleName&gt; block allows you to specify named
stylesheets. An example that implements printable/default views of a
document might be:
</para>
<programlisting>
&lt;AxMediaType screen&gt;
  &lt;AxStyleName #default&gt;
    AxAddProcessor text/xsl /styles/article_html.xsl
  &lt;/AxStyleName&gt;
  &lt;AxStyleName printable&gt;
    AxAddProcessor text/xsl /styles/article_html_print.xsl
  &lt;/AxStyleName&gt;
&lt;/AxMediaType&gt;
</programlisting>
<para>
By mixing the various embedded tags, it is possible to build up a very
feature rich sitemap of how your files get processed.
</para>
</sect1>
<!--
<sect1>
<title>A Complete Example</title>
<para>
A complete ready-to-run phonebook application that can display your
phonebook in both WAP and HTML formats is available to download at
http://axkit.org/examples/phonebook.tar.gz . The example demonstrates
how to use XSP components rendered in different ways (list, view and
edit) to build up a quite complex application.
</para>
</sect1>
-->
<sect1>
<title>Footnotes</title>
<para>
1 The W3C calls it's approved specifications &quot;Recommendations&quot;, rather
than &quot;standards&quot;, because they are an industry consortium, rather than
a standards body. However most people consider thier recommendations
to be standards, because they almost always become de-facto standards.
</para>
<para>
2 AxKit is very flexible in how it lets you transform the XML on the
server, and there are many modules you can plug in to AxKit to allow
you to do these transformations. For this reason, the AxKit
installation does not mandate any particular modules to use, instead
it will simply suggest modules that might help when you install AxKit.
</para>
<para>
3 While we share the XSP syntax with Cocoon, Cocoon allows you to
embed Java code in your XSP, while AxKit only allows you to embed Perl
code.
</para>
<para>
4 AxKit and Cocoon's ESQL taglibs are identical apart from a few minor
deviations, such as how columns of different types are returned, and
how errors are trapped (in Cocoon there are ESQL tags for trapping
errors, whereas AxKit uses exceptions).
</para>
</sect1>
</article>
