Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 22a02ab88ee7099ea6d7fdf524536d58 > files > 21

apache-mod_xslt2-1.3.8-1.2004112100.14mdv2010.0.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Writing XML for mod-xslt2</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="mod-xslt2 Users and Administrators Manual"
HREF="index.html"><LINK
REL="PREVIOUS"
TITLE="mod-xslt2 Setup and Usage"
HREF="x181.html"><LINK
REL="NEXT"
TITLE="Security considerations"
HREF="x800.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>mod-xslt2 Users and Administrators Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x181.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x800.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN413"
>6. Writing XML for mod-xslt2</A
></H1
><P
>Although mod-xslt2 uses standard libraries to parse xml data and transform it, 
there are few things to keep in mind while writing xml/xslt to be parsed by 
mod-xslt2.</P
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN416"
>6.1. XSLT Parameters</A
></H2
><P
>Before anything else, you can access many mod-xslt2 parameters using the 
standard ``value-of'' xslt tag or standard XPath expressions.</P
><P
>As an example, to put the value of the version of modxslt being used in
the output generated by a stylesheet, you could use something like:

<PRE
CLASS="SCREEN"
>  # To output version of mod-xslt2
&lt;xsl:value-of select="$modxslt-version" /&gt;

  # To check interface version
&lt;xsl:if test="$modxslt-interface &amp;lt; 1"&gt;
  mod-xslt2 interface version is greater than 1!
&lt;/xsl:if&gt;</PRE
>
At time of writing, the following variables are made available to the
xslt file by mod-xslt2:

<P
></P
><UL
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-interface</I
></SPAN
> - holds the interface version being used
by mod-xslt2. It is changed every time a new variable is added
to this list and every time a new element is introduced 
(see section element extensions). Variables are not
supposed to be ever removed, so you can safely assume any greater
version number is backward compatible. Current version is ``2''. 
Unless otherwise specified, variables have been introduced in
interface version 1. In version 2, the only added variable
is modxslt-conf-xinclude.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-sapi</I
></SPAN
> - name of the sapi which is now parsing
the xml document. It is usually set by the application making
use of libmodxslt0.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-name</I
></SPAN
> - name of mod-xslt2.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-handler</I
></SPAN
> - name of handler being used by mod-xslt2.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-namespace</I
></SPAN
> - URL of the namespace for mod-xslt2 extensions.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-libpcre</I
></SPAN
> - has value ``true'' if mod-xslt2 was compiled with libpcre support. </P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-exslt</I
></SPAN
> - has value ``true'' if mod-xslt2 was compiled with exslt support. </P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-xinclude</I
></SPAN
> - introduced in interface version 2 - has value 
``true'' if mod-xslt2 was compiled with xinclude support. </P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-extensions</I
></SPAN
> - has value ``true'' if mod-xslt2 was compiled to provide extension 
elements (see dedicated section)</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-libxmlthreads</I
></SPAN
> - has value ``true'' if libxml supports threads.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-libxslthack</I
></SPAN
> - has value ``true'' if configure was given the parameter ``--enable-libxslt-hack''</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-conf-fallbackwrap</I
></SPAN
> - has value ``true'' if configure was given the parameter ``--enable-fallback-wraparound''</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-version</I
></SPAN
> - its value is the current version of the mod-xslt2 being used (example: "1.2.3")</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-version-major</I
></SPAN
> - its value is the first digit of the version (in the example above, "1")</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-version-minor</I
></SPAN
> - its value is the second digit of the version (in the example above, "2")</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>modxslt-version-patchlevel</I
></SPAN
> - its value is the third digit of the version (in the example above, "3")</P
></LI
></UL
>
 
Variables that have value ``true'' when a feature is enabled, have 
value ``false'' when it is not.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN470"
>6.2. mod-xslt2 Extensions</A
></H2
><P
>mod-xslt2 allows you to access many other variables by providing 
custom extension tags.</P
><P
>Those extension tags are available only when you compile mod-xslt2 without
``--disable-extensions'' and if you enable them in your xsl by 
specifying something like:

<PRE
CLASS="SCREEN"
>&lt;xsl:stylesheet version="1.0" 
    extension-element-prefixes="yaslt"
    xmlns:yaslt="http://www.mod-xslt2.com/ns/1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;</PRE
>

Note the ``extension-element-prefixes'' and 
``xmlns:yaslt="http://www.mod-xslt2.com/ns/1.0" that specify that the
extensions will live in the ``yaslt:'' namespace.</P
><P
>However, enabling the extensions will allow you to use two more additional
tags:

<P
></P
><UL
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>header-set</I
></SPAN
> - to set an output header. The only valid attribute
is ``name'', you can use to specify the name of the output header you
want to set.</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>value-of</I
></SPAN
> - to fetch a mod-xslt2 specific variable. The only valid
attribute is ``select''. The value of the ``select'' attribute will
be parsed as a ``mod-xslt2'' expression, which follows completely different
rules than XPath expressions.</P
></LI
></UL
>

Since those tags are provided by extensions, you need to specify the 
namespace every time you use them. In the example above, the namespace to
use would be ``yaslt:'', as specified by the ``extension-element-prefixes''
and ``xmlns'' attributes.</P
><P
>A more complete example may be the following one:

<PRE
CLASS="SCREEN"
>&lt;xsl:stylesheet version="1.0"
    extension-element-prefixes="yaslt"
    xmlns:yaslt="http://www.mod-xslt2.com/ns/1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  &lt;xsl:template match="faq"&gt;
    &lt;yaslt:value-of select="$HEADER[Host]" /&gt;

    &lt;yaslt:header-set name="X-Powered-by"&gt;
      &lt;xsl:value-of select="$modxslt-version" /&gt;
    &lt;/yaslt:header-set&gt;
    
  &lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;</PRE
>&#13;</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN485"
>6.2.1. header-set</A
></H3
><P
>header-set allows you to set a value in the http headers
that will be returned back to the client. Any name
is accepted, as is any value. If ``strip-space'' (&lt;xsl:strip-space elements=...)
is active for the given element, any sequence of blank
characters or new lines is replaced by a single space. 
This feature allows you to specify multi-line headers
(probably invalid for the http protocol) while keeping
everything working. Note that header-set won't try 
to prevent you from doing stupid things. That's up
to you. The only thing you won't be able to do 
is to set the ``Content-Type'', which is handled
by some specific code.</P
><P
>Anyway, ``header-set'' requires just the ``name'' 
attribute to be specified, to select which header
you want to set. Between the opening ``header-set''
and the closing ``/header-set'', you can use any
any element you want, just watch out for new lines and strange
characters that may invalidate your headers.</P
><P
>The following are all valid usage examples
of ``header-set'':

<PRE
CLASS="SCREEN"
>&lt;xsl:stylesheet version="1.0" 
    extension-element-prefixes="yaslt"
    xmlns:yaslt="http://www.mod-xslt2.com/ns/1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  [...]
    &lt;yaslt:header-set name="X-Powered-by"&gt;
      &lt;xsl:value-of select="$modxslt-version" /&gt;
    &lt;/yaslt:header-set&gt;

    &lt;yaslt:header-set name="X-Fuffa"&gt;
      fuffa
    &lt;/yaslt:header-set&gt;
    &lt;yaslt:header-set name="X-Foo"&gt;
      &lt;xsl:apply-templates /&gt;
    &lt;/yaslt:header-set&gt;
  [...]

&lt;/xsl:stylesheet&gt;</PRE
>&#13;</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN491"
>6.2.2. value-of - modxslt expressions</A
></H3
><P
>value-of allows you to fetch any mod-xslt2 specific
variable or expression.</P
><P
>While writing mod-xslt2 code, I decided to keep most of
mod-xslt2 variables in a completely independent 
and isolated namespace mainly for three reasons:

<P
></P
><UL
><LI
><P
>Some of the variables names and values are gathered
from the running environment, which, by no means, can
be considered safe or trusted.</P
></LI
><LI
><P
>For the same reason, mod-xslt2 variable names can violate XPath
specifications, and I didn't want to employ weird name
mangling routines.</P
></LI
><LI
><P
>Work is underway to cache xml and xslt meta data to speed things up.	
In order to do so, it is however necessary to intercept any access
to modxslt variables.</P
></LI
></UL
>

For the same reasons, I decided to go with my own (simple) language to
parse expressions.</P
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN502"
>6.2.2.1. Simple expressions</A
></H4
><P
>An expression is a list of characters which contains one or more variables.
Each variable starts with a ``$'' symbol and is followed by the name of
the variable or by the name of the variable enclosed in curly brackets 
(``{'', ``}''). The following are all valid expressions:

<PRE
CLASS="SCREEN"
>0: "this is fuffa"
1: "$fuffa"
2: "${fuffa}"
3: "this is ${fuffa}"
4: "this is much $fuffa more"</PRE
>

Expression 0 is a ``simple'' string, no replacements are done, while
expression 1 is replaced by the value of variable ``fuffa''.</P
><P
>Expression 2 is exactly like expression 1, beside the fact that using
``{'' ``}'' would allow this variable to be correctly replaced even in 
a string like ``ababa${fuffa}ababa''. Expression 3 would be replaced
by the value of variable ``$fuffa'' preceded by ``this is'', much 
like in expression 4.</P
><P
>Non existent variables are replaced by the empty string (they are removed),
while a ``$'' which should be part of the string should be escaped
by preceding it with a ``\''. This also implies that any ``\'' should
be itself escaped by using a double back slash (``\\'').</P
></DIV
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN508"
>6.2.2.2. Indirect references and built up variable names</A
></H4
><P
>The usage of ``${'' and ``}'' allows you to use indirect references:
let's say that ``$foo=bar'' and that ``$bar=fuffa'', evaluating
the expression ``${$foo}'' would at first be replaced by ``${bar}''
and then replaced by ``fuffa'', much like in bash programming.</P
><P
>There is more to say: inside a ``{'' and ``}'' you could even
put more than one variable or character constants, to ``build'' up
the name of the variable you want to be replaced.</P
><P
>Let's make one more example and let's say ``$fuffa=hello'', 
``$foo=fuf'' and ``$bar=fa''. In this case, we would have
the following output (given the expressions on the left):

<PRE
CLASS="SCREEN"
>${$foo$bar} -&#62; ${fuffa} -&#62; hello
${${foo}$bar} -&#62; ${fuffa} -&#62; hello
${${foo}fa} -&#62; ${fuffa} -&#62; hello
${fuf$bar} -&#62; ${fuffa} -&#62; hello</PRE
>

Using those expressions, you could have as much fun as you want
and recurse as much as you want (and your stack holds).</P
></DIV
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN514"
>6.2.2.3. Predefined variables (array like variables)</A
></H4
><P
>The ability of parsing variables is not such a good thing if we
don't have variables to parse. However, mod-xslt2 provides a rich set 
of predefined variables. Variables are grouped in classes that
look like ``arrays''. The main arrays available are:

<P
></P
><UL
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>MODXSLT</I
></SPAN
> - holds the same variables as passed as
parameters to the xslt parser (described in
the previous sections). Those variables hold informations
like how mod-xslt2 was compiled or what features are enabled</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>GET</I
></SPAN
> - contains variables passed to your xml file
as GET parameters (http get)</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>HEADER</I
></SPAN
> - contains the headers passed to mod-xslt2
by your web server (headers that, in turn, were given
by the client)</P
></LI
></UL
>

As often happens, it is easier to explain the usage of something
by showing some examples than trying to explain how it works:

<PRE
CLASS="SCREEN"
>$GET[fuffa]
$HEADER[User-Agent]
$MODXSLT[version]
$MODXSLT[namespace]</PRE
>

In the examples above, the first line fetches the variable ``fuffa''
that was passed as a get parameter to the xml file (with something
like http://host.fqdn/file.xml?fuffa=value).</P
><P
>The second line is replaced by the header ``User-Agent'' provided
by the client, while the third and fourth lines are replaced respectively
by the value of the parameter $modxslt-version and $modxslt-namespace.</P
><P
>Using GET, you can access any ``get'' parameter that was passed to your xml 
file while HEADER gives you access to any header that was sent to you by 
the client.</P
><P
>Keep also in mind that, as explained in the previous sections, it is possible 
to build up the name of a variable from other variables. So, the following
is also valid:

<PRE
CLASS="SCREEN"
>$HEADER[$GET[header-to-check]]
${$source[User-Agent]}</PRE
>

Watch out not to insert any space between the square brackets (``['', ``]'') and the
array index, since they are not allowed and the variable won't be substituted.</P
></DIV
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN532"
>6.2.2.4. Setting variables</A
></H4
><P
>It is also possible to create custom variables from .xml files to be passed
over to the xslt. To do so, you need to use the Processing Instruction ``modxslt-param''
with the attributes ``name'' and ``value'', where ``name'' specifies the name of the
variable to be set while ``value'' specifies its value.</P
><P
>Using this processing instruction, you can also override the value of predefined
variables, like $GET[fuffa], but not of mod-xslt2 constants, like $MODXSLT[version].</P
><P
>However, let's see a complete example of using modxslt-param:

<PRE
CLASS="SCREEN"
>&lt;?xml version="1.0" encoding="ISO-8859-1" 
	standalone="yes"?&gt;

&lt;!DOCTYPE fuffa SYSTEM "dtd/fuffa.dtd"&gt;

&lt;?modxslt-param name="variable" value="its value" ?&gt;

[...]</PRE
>

The variable ``$variable'' would thus be accessible from your xslt
using modxslt own ``value-of'', with something like ``...:value-of select="$variable"''.</P
><P
>Note also that some SAPI allow you to pass over parameters to your
xml or xsl files from configuration files. Refer to the SAPI specific 
section of this manual.</P
></DIV
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN539"
>6.2.3. Verifying availability of mod-xslt2 extensions</A
></H3
><P
>Before using any of the mod-xslt2 xslt extensions described in the
previous sections, you should make sure they are available on your
system and version of mod-xslt2.</P
><P
>As a first test, you can verify your xslt is being used by mod-xslt2
by checking the value of the XPath param ``modxslt-interface''. If available,
you can then verify that ``modxslt-conf-extensions'' has value true, and
assume extensions are available.</P
><P
>One alternative to using mod-xslt2 params is to use the standard
functions defined in http://www.w3.org/TR/1999/REC-xslt-19991116#extensions: 

<PRE
CLASS="SCREEN"
>boolean element-available(string)
boolean function-available(string)</PRE
>

to verify mod-xslt2 extension tags are available, with something like:

<PRE
CLASS="SCREEN"
>&lt;xsl:if test="element-available('yaslt:value-of')"&gt;
  &lt;yaslt:value-of select="$HEADER[User-Agent]" /&gt;
&lt;/xsl:if&gt;</PRE
>

assuming that in the opening ``xsl:stylesheet'' tag you
specified as extension name ``yaslt''.</P
><P
>There's one more way to handle the availability of mod-xslt2
extensions: using the ``xsl:fallback'', like in this example:

<PRE
CLASS="SCREEN"
>  &lt;yaslt:value-of select="$HEADER[User-Agent]"&gt;
    &lt;xsl:fallback&gt;
      Sorry, cannot access headers 
       (no mod-xslt2 extensions available)
    &lt;/xsl:fallback&gt;
  &lt;/yaslt:value-of&gt;</PRE
>

In this case, if ``yaslt:value-of'' is not available
the xslt processor will parse the content of the ``xsl:fallback'' node.
In any other case, the ``xsl:fallback'' node will be completely
ignored.</P
><P
>However, at time of writing, libxslt-1.0.32 has a few
bugs handling fallback nodes:

<P
></P
><UL
><LI
><P
>when the extension is available, the fallback node 
is not ignored as ought to be and a warning is printed
in your web server logs (read the FAQ for more information
about this issue)</P
></LI
><LI
><P
>when the warning is printed, libxslt-1.0.32 calls the
error handler with the wrong parameters, possibly causing 
a segmentation fault (it happens if libxslt debugging
was enabled, in which case one of the pointer passed to
mod-xslt2 is not null and considered to be valid)</P
></LI
></UL
>

There are a few ways to avoid this problem:

<P
></P
><UL
><LI
><P
>patch the library in order to avoid the warning to be printed </P
></LI
><LI
><P
>patch the library in order for the correct arguments to be always passed
to error functions</P
></LI
><LI
><P
>compile mod-xslt2 specifying ``--enable-fallback-wraparound'', to
ask mod-xslt2 to remove ``fallback'' nodes when the extensions are
available</P
></LI
><LI
><P
>compile mod-xslt2 specifying ``--enable-libxslt-hack'', to ask
mod-xslt2 to always enable debugging using some wrappers, in
order to avoid the error highlighted above</P
></LI
></UL
>

Those are really two libxslt bugs, where the first one triggers the second
one. Correcting one of the two should be enough for mod-xslt2 to work. However,
the best way to solve the problem is by using the two highlighted patches.
Please read ``README.Patches'' to know more about those issues.</P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN563"
>6.3. Setting the Content-Type (MIME type) of the parsed document</A
></H2
><P
>As indicated in the previous sections, you are not allowed to use
``header-set'' to try to change the ``Content-Type'' of the document.</P
><P
>However, you can choose the mime type of the document by specifying the
attribute ``media-type'' in the ``xsl:output'' tag, as shown 
in the example below:

<PRE
CLASS="SCREEN"
>&lt;xsl:output media-type="text/html" 
	encoding="ISO-8859-1" /&gt;</PRE
>

If no media-type is specified, mod-xslt2 will try to guess it (relying on libxml2
parsing), probably returning back to the client a media-type of ``text/plain'', 
``text/xml'' or ``text/html''.</P
><P
>Keep in mind that you can specify any ``media-type'' you want.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN569"
>6.4. Choosing the stylesheet to use</A
></H2
><P
>mod-xslt2 decides which stylesheet to use thanks to a 3 steps procedure:

<P
></P
><OL
TYPE="1"
><LI
><P
>if any suitable &lt;?xml-stylesheet or &lt;?modxslt-stylesheet processing
instruction is found, the specified stylesheet is used, regardless of 
any XSLTSetStylesheet parameter. The first suitable xml-stylesheet 
or modxslt-stylesheet is chosen.</P
></LI
><LI
><P
>if a XSLTSetStylesheet is provided for the given document type, the
specified stylesheet is used.</P
></LI
><LI
><P
>in any other case, a 500 server error is returned (the rationale
is that once mod-xslt2 is told to parse the document, mod-xslt2 
will either output the parsed document or send an error back to
the client).</P
></LI
></OL
>

We already talked about XSLTSetStylesheet in the SAPI specific
sections, and there's not much more to say here.</P
><P
>However, as you can see in the first step, mod-xslt2 can be told 
which stylesheet to use using two different processing instructions: 
xml-stylesheet and modxslt-stylesheet.</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN580"
>6.4.1. xml-stylesheet and modxslt-stylesheet</A
></H3
><P
>xml-stylesheet is a standard xml directive, and its description and
usage can be found on  http://www.w3.org/TR/xml-stylesheet. As
you probably already know, xml-stylesheet can be used to associate
a given xml file with the xslt to be used and generally looks something like:

<PRE
CLASS="SCREEN"
>&lt;?xml-stylesheet 
	type="text/xsl" 
	href="./xslt/faq-http.xsl" 
	media="screen" 
	alternate="no" 
	title="For any web browser" 
	charset="ISO-8859-1"?&gt;</PRE
>

For a given stylesheet to be considered ``suitable'' by mod-xslt2
to parse an xml file, the following conditions must be met:

<P
></P
><UL
><LI
><P
>type - must be either ``text/xml'' or 
``text/xsl''.</P
></LI
><LI
><P
>href - should contain the url of the stylesheet. 
See the next section on ``Accepted urls'' .</P
></LI
><LI
><P
>media - either ``all'' or ``screen''. 
In case of ``screen'', it can be followed
by one or more ``media expressions''. The stylesheet
will be considered ``suitable'' only if one
of the expressions is evaluated to have a ``true''
value. The ``empty'' expression
is considered to always match (be true). See the section
on ``Media expressions'' .</P
></LI
></UL
>

At time of writing, the other fields are of no interest
to mod-xslt2.</P
><P
> 
The main difference between ``xml-stylesheet'' and 
``modxslt-stylesheet'' is that the first one should
be used in a way compliant with the highlighted standards,
while the second one may use any mod-xslt2 extension.</P
><P
>Keep in mind, however, that mod-xslt2 will not complain
if you use its extensions in the standard ``xml-stylesheet''
tag.</P
><P
>modxslt-stylesheet is a processing instructions that takes
exactly the same arguments as xml-stylesheet, and it 
has been introduced mainly for three reasons:

<P
></P
><UL
><LI
><P
>As not being standardized, it is interpreted
only (and exclusively) by mod-xslt2. If a 
browser or another xslt processor finds any
modxslt-stylesheet directive, it will completely
ignore it. This allows few useful tricks that
will be discussed in the next few sections.</P
></LI
><LI
><P
>currently, the standard says that the ``media''
attribute ``may'' contain expressions, which are not
yet defined in any standard and that may be 
defined in the future (AFAIK). Browsers or 
xslt-processors are thus supposed to ignore them and 
skip anything after the first ``word'' followed by a space until
the first comma. However, mod-xslt2 supports its own 
language for expressions, language that may be used in 
``modxslt-stylesheet'' without fears to conflict
with future standards or incompatible browsers.</P
></LI
><LI
><P
>as you probably know, in case a stylesheet is
not found or is not valid, mod-xslt2 will give the user 
back a ``server error'' (the rationale is that if a document
was meant to be parsed the inability to do so is an
error). However, the ``modxslt-stylesheet'' pi provides
a simple mechanism to return back to the browser the
plain xml in order to let the browser parse it.
This feature, combined with ``media expressions'', would
allow you to configure mod-xslt2 to parse only those xml
files that would cause problems to the various browsers
on the market.</P
></LI
></UL
>

A couple examples will be given in the following sections.</P
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN601"
>6.4.1.1. Media expressions</A
></H4
><P
>As you probably know, the ``media'' attribute in a 
xml-stylesheet (or modxslt-stylesheet) processing 
instructions may contain a comma separated list of 
``media types'' for which the stylesheet should be used
to parse the xml data.</P
><P
>A media attribute usually looks something like:

<PRE
CLASS="SCREEN"
>&lt;xml-stylesheet ... media="screen, printer"...</PRE
>

where the media ``all'' is a sort of wildcard,
specifying that a stylesheet could be used to
parse xml data to be outputted on any media.</P
><P
>Any xslt processor should also ignore anything 
from the first space following the name of a media 
type to the first comma (or end of attribute), 
since ``in the future'' some kind of 
``expressions'' may be introduced by the standards.</P
><P
> 
Any xslt processor looking for a ``screen'' media
stylesheet, should thus accept anything like

<PRE
CLASS="SCREEN"
>&lt;xml-stylesheet media="screen fuffa fuffa, printer"
or
&lt;xml-stylesheet media="screen foo bar"</PRE
>

where ``fuffa fuffa'' or ``foo bar'' are ``Media
expressions'' that should be ignored.</P
><P
>mod-xslt2 introduces its own language to specify 
media expressions. </P
><P
>A mod-xslt2 expression is usually a boolean expression
preceded by an ``and'' made of a list of tests that must 
be passed for the stylesheet to be used. Tests may make 
use of mod-xslt2 variables and of many operators that will 
be described in the following sections.</P
><P
>Mod-xslt grammar to parse expressions could
be described by a BNF similar to the following:

<PRE
CLASS="SCREEN"
>bool_expr: 
	| cmp_expr 
	| cmp_expr ','
;

cmp_expr: '(' cmp_expr ')' 
	| '!' cmp_expr 
	| cmp_expr BooleanOperator cmp_expr 
	| String StringOperator String
	| String
;</PRE
>

Where capitalized strings are terminals and
lowercase strings are non-terminals.</P
><P
>Associativity of operators and their precedence
will be shown in the next sections.</P
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN614"
>6.4.1.1.1. Strings</A
></H5
><P
>A string can be specified by using the name
of a variable, a sequence of characters that
match the regular expression:

<PRE
CLASS="SCREEN"
>[^[:blank:]*+%/\"\',!&gt;&lt;=~()-]*</PRE
>

or a sequence of any character enclosed in single
or double quotes (&apos;, &quot;), where any 
``&apos;'' or ``&quot;'' part of the sequence
itself is escaped by prepending it with a ``\''.</P
><P
>Strings enclosed in single or double quotes may
also contain ``mod-xslt2 expressions'', as described
in the section  ``value-of - mod-xslt2 expressions''
and contain any of the specified variables.</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN619"
>6.4.1.1.2. String Evaluation</A
></H5
><P
>As shown in the BNF grammar, a String can be used both
in a ``boolean'' or ``cmp'' context (either, checked
with a BooleanOperator or StringOperator). In boolean
context, a String is considered true if it does not
correspond to the empty string ("") or if the variable
is defined (has a value associated with it, regardless
of what the value is).</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN622"
>6.4.1.1.3. Boolean Operators</A
></H5
><P
>mod-xslt2 recognizes the following left associative 
boolean operators:

<P
></P
><UL
><LI
><P
>1 - ``!'' - logical negation (left associative)</P
></LI
><LI
><P
>2 - ``and'' - logical and (left associative)</P
></LI
><LI
><P
>2 - ``or'' - logical or (left associative)</P
></LI
></UL
>

Where the precedence of the operators is determined
by the number (lower the number, higher the precedence).</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN632"
>6.4.1.1.4. String Operators</A
></H5
><P
>mod-xslt2 recognizes the following string operators:

<P
></P
><UL
><LI
><P
>``=='' or ``='' - equal, true if the left side of the operator
is equal to the right side. At time of writing, ``='' and
``=='' have the same meaning and return a true value if
the memory representation of the string on the left
is the same of that on the right. In the future, ``=='' 
will maintain this meaning, while ``='' will be used
to compare the value of the number on the left with that
of the number on the right (taking care of roundings and
of processor precision limits).</P
></LI
><LI
><P
>``!='' - unequal, true if the left side of the operator
is not equal to the right side. By equal we mean that
the memory representation of the string on the left is 
the same as that on the right.</P
></LI
><LI
><P
>``=~'' - perl regular expression matches, true if the
regular expression on the right of the operator matches
the string on the left. See next section on regular
expressions  for more details.</P
></LI
><LI
><P
>``!~'' - perl regular expression does not match, true
if the regular expression on the right of the operator
does not match the string on the left. See next section
on regular expressions  for more details.</P
></LI
><LI
><P
>``&gt;'', ``&gt;='', ``&lt;'', ``&lt;='' - true respectively
when the string on the left of the operator, converted to
a ``real'', is greater, greater or equal, less, less or equal,
to the value of the string on the right converted to a
``real''.  </P
></LI
></UL
>&#13;</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN646"
>6.4.1.1.5. Perl Compatible Regular Expressions</A
></H5
><P
>The operators ``=~'' and ``!~'' allow you to match a String
with a perl compatible regular expressions, also known as 
PCRE.</P
><P
>mod-xslt2 makes use of ``libpcre'' to parse and apply those
expressions. The complete reference of those regular expressions
can thus be found in perlre(1) on any unix system with perl installed, 
while a quick tutor and introduction can be found on perlretut(1) or
perlquick(1) and on any book about perl programming.</P
><P
>In mod-xslt2, PCRE are specified by enclosing them in a ``separator'',
and by indicating one or more options after the second occurrence of the
separator. A separator may be any character beside ``\'', which can be 
used to escape the separator itself if needed in the regular expression. 
Additionally, regular expressions may be enclosed in single or double quotes, to
overcome the limits of characters a String can contain as specified
in the previous sections.</P
><P
>Keep also in mind that, as being specified in a xml attribute, any
entity must also be escaped using standard xml notation.</P
><P
>In any case, the following options may be specified:

<P
></P
><UL
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>i</I
></SPAN
> - using this option, case insensitive matching is performed</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>e</I
></SPAN
> - using this option, the ``$'' matches only the end of the string and does
not match any newline the string may contain</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>a</I
></SPAN
> - using this option, the match must be ``anchored'', which means it must match
from the beginning to the end of the string</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>s</I
></SPAN
> - using this option, the ``.'' matches also newlines </P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>x</I
></SPAN
> - using this option, spaces inside a regular expression are ignored unless
they are escaped</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>X</I
></SPAN
> - using this option, you will enable libpcre features not compatible with perl.
At time of writing, enabling this option will cause an error every time an unknown character
is escaped (prepended with a ``\'')</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>m</I
></SPAN
> - using this option, you will enable multiline matching</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>y</I
></SPAN
> - this option ``inverts the greediness of the quantifiers, so that they are not greedy by
default, bug become greedy if followed by ?'' (from pcreapi(3))</P
></LI
><LI
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>u</I
></SPAN
> - this option causes PCRE to consider both the pattern and the string as made of UTF-8 encoded
characters</P
></LI
></UL
>

The following are all examples of valid regular expressions:

<PRE
CLASS="SCREEN"
>'/fuffa/i' - match ``fuffa'', ``Fuffa'', ``FUFFA'',
	``abfuffabc''...
'$bap$ia' - match ``bap'', ``Bap'', ...
'$a\\\$$i' - match any string containing ``a$''. In this
	case, ``$'' is escaped twice to avoid it being
	considered ``the terminator'' and to avoid any
	meaning as regular expression special character.
'&amp;amp;fuffa&amp;amp;i' - exactly like the first example,
	but using ``&amp;'' as separator</PRE
>

Note that I have always enclosed them in quotes, to avoid causing
problems to the parser.</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN682"
>6.4.1.1.6. Examples of complete media expressions</A
></H5
><P
>&#13;<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... media="fuffa" ... &gt;</PRE
>

will return false, and the stylesheet not applied.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... media="all" ... &gt;</PRE
>

will return true, and the stylesheet applied.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... media="screen" ... &gt;</PRE
>

will return true, and the stylesheet applied.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... media="screen and 
  '$HEADER[User-Agent]' =~ '/msie/i'" ... &gt;</PRE
>

will return true only if the header ``User-Agent'' contains the string ``msie'' compared
using case insensitive matching.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... 
  media="screen and 
  	  '$HEADER[User-Agent]' =~ '/msie/i' or 
          '$HEADER[User-Agent]' =~ '/Moz.*1\.0/'" 
	  ... &gt;</PRE
>

will return true if the header ``User-Agent'' contains the string ``msie'' compared
using case insensitive matching or contains the string ``Moz'' followed by any number of
any character as long as it is followed by the string ``1.0''.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... 
  media="fuffa, screen and $GET[ignorebrowser] or 
          '$HEADER[User-Agent]' =~ '/Moz.*1\.0/'" 
	  ... &gt;</PRE
>

will return true when the xml page was called by a browser with a get
parameter ``ignorebrowser'' with any value (with something like 
http://url.of.xml.document.org/path/to/xml/document.xml?ignorebrowser=1)
or if the header ``User-Agent'' contains the string ``Moz'' followed
by ``1.0''.

<PRE
CLASS="SCREEN"
>&lt;modxslt-stylesheet ... 
  media="fuffa, screen and 
           $MODXSLT[interface] &#62;= 1 and
  	   $MODXSLT[sapi] = apache1"</PRE
>

will return true when the interface version of mod-xslt2 
is greater than or equal to 1 and when the sapi which is 
parsing the xml document is ``apache1''. This is especially
useful if your xsl stylesheet rely on some server specific
variable/feature being available.</P
><P
>Keep also in mind that you can use as many ``moxslt-stylesheet''
or ``xml-stylesheet'' as you want. In any case, the first matching
one will be used by mod-xslt2. If none applyable will be found,
a 500 error page will be returned. The rationale is that if you
want a document to be parsed (and configure mod-xslt2 to do the
parsing), the document will be either be parsed and returned back
to the browser or an error given back without disclosing of any
additional information.</P
></DIV
></DIV
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN693"
>6.4.1.2. href URLs</A
></H4
><P
>Well, up to now we have seen how our .xml files can specify which
xslt to be used. However, we haven't seen where the .xsl files can
be stored and how we can specify their path.</P
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN696"
>6.4.1.2.1. Supported URL schemes</A
></H5
><P
>At time of writing, mod-xslt2 (thanks to libxml2), can fetch xsl,
dtd or other .xml files using one of the following methods:

<P
></P
><OL
TYPE="1"
><LI
><P
>remote http URL</P
></LI
><LI
><P
>remote ftp URL</P
></LI
><LI
><P
>local file URL</P
></LI
><LI
><P
>local http URL</P
></LI
></OL
>

The first three methods are quite standard and made
available thanks to libxml2 handlers. However,
there are a few things to keep in mind:

<P
></P
><UL
><LI
><P
>a http URL <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>must</I
></SPAN
> start with ``http://''
and could contain a port number, an username
and a password, like in <TT
CLASS="FILENAME"
>http://carlo%password@www.masobit.net:7568/file.php</TT
>.</P
></LI
><LI
><P
>a ftp URL <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>must</I
></SPAN
> start with ``ftp://''
and follow the same conventions as the http URL
shown above.</P
></LI
><LI
><P
>a file URL <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>may</I
></SPAN
> start with ``file://''
or just be an absolute or relative path. If it
starts with ``file://'', ``file://'' is removed
from the URL and the remaining path is opened.
Thus, something like ``file:///file.xsl'' points
to ``file.xsl'' in the ``root'' (/) of the file system,
while ``file://file.xsl'' indicates ``file.xsl''
in the same directory of the xml file referring to
that url. Both could been given using a path like 
``/file.xsl'' or ``file.xsl'', without any preceding
``file://'' (which is stripped anyway).</P
><P
>In short, it should follow the same syntax and behavior
as indicated on rfc 1738, 1808 and 2396.</P
></LI
></UL
>

There is a fourth url scheme supported by mod-xslt2:
local://.</P
><P
>local:// behaves exactly like a local file URL,
but tells mod-xslt2 that the file should be fetched
using the http protocol. This scheme allows you
to easily use .xsl or dtd generated by cgi or
php scripts, without using a remote connection.</P
><P
>As you may notice, there are thus at least three good
reasons to use ``local://'' instead of ``http://'':

<P
></P
><UL
><LI
><P
>Before anything else, ``local://'' is like 
the ``file://'' scheme, and allows you to easily
specify urls relative to the path of the file
using the url itself. For example, if you fetch
http://www.masobit.net/fuffa/doc.xml and doc.xml
requires ``local://xslt/doc.xsl'', the file
``http://www.masobit.net/fuffa/xslt/doc.xsl'' will be
fetched using the http protocol (and thus, allowing
doc.xsl to be a php script or cgi-bin).</P
><P
>In contrast, ``local:///xslt/doc.xsl'' would refer
to ``http://www.masobit.net/xslt/doc.xsl'', much 
like ``file://''.</P
></LI
><LI
><P
>In second instance, if you use virtual domains
and you want to make use of locally generated
xsl files, you cannot reliably use the 
``http://'' scheme. As you may guess, in 
``virtual'' environments ``http://localhost/xslt/doc.xsl'' 
would not be necessarily the same as 
``http://www.masobit.net/xslt/doc.xsl'', and there
would be no way to specify a relative url if 
``local://'' was not available.</P
></LI
><LI
><P
>Instead of using an outgoing connection, when a ``local://''
url is specified a ``subrequest'' is made, allowing

<P
></P
><UL
><LI
><P
>faster retrieval of generated documents</P
></LI
><LI
><P
>easy detection of loops  (more about
loops will be discussed later)</P
></LI
><LI
><P
>to avoid a deadlock that may halt mod-xslt2
(and that halts any mod-xslt2 I have seen on 
the internet) under very high loads (which a
malicious user may use to cause a denial of service)</P
></LI
></UL
>&#13;</P
></LI
></UL
>&#13;</P
></DIV
></DIV
><DIV
CLASS="SECT4"
><H4
CLASS="SECT4"
><A
NAME="AEN737"
>6.4.1.3. HTTP glinces</A
></H4
><P
>If you use http urls, either for external DTDs or for xsl stylesheets,
watch out for a small problem it may arise: libxml2, by default, when
fetching a remote document, does not check for the http status of the web 
server. The result is that, libxml2, will try to parse everything that
will be returned back to the browser, even a 404 or 500 error page.</P
><P
>Some believe this behavior is correct, others believe error pages
should be considered exactly like a file system error. However, independently
from what I think, this behavior leads to strange results when parsing
documents: for example, if a DTD is missing on the local file system,
the problem is ignored, but if it is missing from a remote url, the 404
page is parsed as the looked up DTD, and a fatal error is produced,
telling the DTD is invalid. Additionally, in your error log you would
see wierd errors telling you about invalid lines in DTDs you know 
nothing about and you cannot find anywhere in the file system.</P
><P
>So, beware, if you find strange errors regarding DTDs or xslt you 
never wrote, verify they are not the 404 or 500 error pages
returned back by a remote server.</P
><P
>There's one more thing to say: I personally don't like this behavior.
I tryed to get rid of it in several ways, but the only way out I found
was either rewrite the http client (or include my own with mod-xslt2) or 
patch libxml2 library.</P
><P
>The first solution didn't seem quite realistic to me, so, in the ``/patches''
directory of the mod-xslt2 tarball, you'll find two patches:

<P
></P
><UL
><LI
><P
>The first one makes libxml2 verify the error status of the remote
web server, and return an error if it is not a 200 or 3xx (in which
case the page the client has been redirected to will be fetched)</P
></LI
><LI
><P
>The second one makes libxml2 export some private data allowing
anybody making use of it to freely choose what to do in case
of errors</P
></LI
></UL
>

Personally, I believe the first patch may break things up. On your system,
you may have applications that rely on libxml2 parsing error pages (I personally
believe those applications should be considered broken anyway). The
second patch, instead, should not break anything.</P
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN749"
>6.4.1.3.1. URL, media and type substitutions</A
></H5
><P
>Additionally, any URL specified in a ``href'' attribute or
the value of the ``type'' and ``media'' attribute in
a &lt;xml-stylesheet or &lt;modxslt-stylesheet may contain
any mod-xslt2 expression , that will be replaced the
first time the expression itself is used.</P
><P
>As an example, you may specify something like:

<PRE
CLASS="SCREEN"
>&lt;?xml-stylesheet type="text/xsl" 
  href="http://www.mbit.net/xslt/faq.php?
    lang=$GET[lang]&amp;agent=$HEADER[User-Agent]"</PRE
>

This is useful to pass over parameters to php or cgi scripts. As you
may already have noted, any generated xsl stylesheet is able to access
to mod-xslt2 variables, but the cgi or php script itself does not have
any access to them, unless you pass them over as get parameters.</P
><P
>Right now, POST requests are not supported and will never be unless
somebody decides it worth and either works on it or bagges me to do 
so.</P
><P
>Note also that URL should be correctly encoded by replacing xml
entities and by replacing any dangerous character with the corresponding
``%'' value.</P
></DIV
><DIV
CLASS="SECT5"
><H5
CLASS="SECT5"
><A
NAME="AEN756"
>6.4.1.3.2. Returning raw xml back to the browser</A
></H5
><P
>Using the processing instruction ``xml-stylesheet''
to select a stylesheet to be used, you must
specify the ``href'' of the stylesheet to be used.
Failure of doing so will result in an error be 
outputted in your logs. However, if you use
``modxslt-stylesheet'', you can omit the ``href''
of the stylesheet to be used. In this case, the
xml will be returned back to the browser without
further processing.</P
><P
>This is quite useful if you know a particular browser
is able to correctly parse your xml files: in this
case, you can use a ``media expression'' to match
the browser, and specify no href for the xml to
be returned back raw to the client, with something
like:

<PRE
CLASS="SCREEN"
>[...]
&lt;modxslt-stylesheet 
  type="text/xsl"
  media="screen and 
    '$HEADER[User-Agent]' =~ '@Gecko.*1\.4@'"
  alternate="no" title="For Mozilla web browser" 
  charset="ISO-8859-1" ?&gt;

&lt;modxslt-stylesheet 
  type="text/xsl"
  href="local://xslt/links.xsl"
  media="screen and 
    '$HEADER[User-Agent]' =~ '@Links@'"
  alternate="no" title="For Links web browser" 
  charset="ISO-8859-1" ?&gt;

&lt;xml-stylesheet
  type="text/xsl"
  href="local://xslt/any.xsl"
  media="screen"
  alternate="no" title="For any other web browser"
  charset="ISO-8859-1" ?&gt;
[...]</PRE
>

In the example above, the xml file would be returned
raw if the request was made by ``mozilla'', would be
parsed using ``xslt/links.xsl'' if the request was made
by ``Links'' while it would be parsed using ``any.xsl''
if the request was made by any other web browser.</P
><P
>If ``mozilla'' was used, the raw document would be then
parsed by mozilla itself, that would ignore any 
``modxslt-stylesheet'' and use as a stylesheet 
``local://any.xsl''. However, mozilla itself wouldn't
understand ``local://'' urls and return an error. Thus, 
in any ``raw'' document returned by mod-xslt2, ``local://''
urls are replaced by standard ``http://'' urls
pointing back to the virtual domain that was used
to issue the request, allowing mozilla to parse
the document without problems. </P
><P
>Additionally, any mod-xslt2 variable used in &lt;xml-stylesheet
processing instruction is replaced before returning back
the raw xml document to the browser.</P
><P
>This feature will be especially useful as more browsers
will correctly support xml and xsl transformations.</P
><P
>Note, however, that variables used in &lt;modxslt-stylesheet 
pi are not replaced: the main reason not to parse them
is that expressions may loose their meaning if variables are
replaced (... screen and 'Mozilla/5.0 Gecho/20031010 Debian/1.4-6' =~ '@Gecko/.*1\.4@' 
??, doesn't seem too smart), and that a browser is able
to understand those PI it should be given all the needed
informations to perform expression evaluation by itself.</P
></DIV
></DIV
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN765"
>6.5. Using external DTDs</A
></H2
><P
>Some believe DTDs are useless to parse xml documents or to
generate http output. However, as you probably know, 
DTDs may be used to provide defaults for certain tags
or provide the definition of entities used by your xml 
document.</P
><P
>However, DTDs are not always useful and parsing one additional 
document may be not a bearable overhead.</P
><P
>The approach used by mod-xslt2 is to parse externa DTDs only
if the document is declared not to be standalone. Thus,
the standalone attribute in your xml declaration is not
ignored:

<PRE
CLASS="SCREEN"
>&lt;?xml version="1.0" encoding="ISO-8859-1" 
	standalone="yes" ?&gt;</PRE
>

tells mod-xslt2 not to load external DTDs, while:

<PRE
CLASS="SCREEN"
>&lt;?xml version="1.0" encoding="ISO-8859-1" 
	standalone="no" ?&gt;</PRE
>

tells mod-xslt2 your xml file needs them. Even if you tell mod-xslt2
to make use of DTDs, just an error will be printed if they are
missing (unless they are fetched using the http protocol, look 
to the section ``HTTP Glinces'').</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN772"
>6.6. Testing xml files and stylesheets from the command line</A
></H2
><P
>Before putting a xml page or newly created php script on your web 
server you may want to test the generated output statically on
your local machine.</P
><P
>Since it may not always be possible to use a web server to verify
them, you may be interested in some command line utilities you
may found useful.</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN776"
>6.6.1. xsltproc</A
></H3
><P
>xsltproc is a tool provided in the libxslt package which can
be used to process xml files from the command line. As
being provided by libxslt, however, it does not support  
mod-xslt2 extensions and uses different error handling
routines.</P
><P
>To use it, you just need to type ``xsltproc file_to_parse.xml''.
The output will be printed on stdout. In case of errors, they
will be printed on stderr.</P
><P
>xsltproc may be useful mainly for two purposes: you can see
what a standard browser (that does not support mod-xslt2 extensions)
would do with your xml documents, and you can profile the
parsing times. xsltproc provides the ``--timing'' parameter
which allows you to know which xslt instructions required
the greatest amount of time to generate the output document,
with something like ``xsltproc --timing file_to_parse.xml''.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN781"
>6.6.2. modxslt-parse</A
></H3
><P
>modxslt-parse looks quite similare to xsltproc. The main 
difference is that modxslt-parse supports all mod-xslt2
extensions and that does not support any command line
parameter, beside the name of the file to parse (output
is sent to standard output). It is quite useful to 
verify a particular .xml file off-line from your command
line. You can use it by simply typing something like:

<PRE
CLASS="SCREEN"
>modxslt-parse file.xml</PRE
>

from your command line. Output will be sent to stdout,
while errors to stderr. Headers set will be discarded.
It internally uses exactly the same engine as mod-xslt2.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN785"
>6.6.3. rxp</A
></H3
><P
>``rxp'' is a tool provided in the rxp package on
http://www.cogsci.ed.ac.uk/~richard/rxp.html.</P
><P
>It can be used to verify validity of xml files
or well-formedness. It should be used to verify the
output of your scripts or the validity of your
xml files before putting them on line.</P
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN789"
>6.7. Other tools provided</A
></H2
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN791"
>6.7.1. modxslt-perror</A
></H3
><P
>Since strerror is not thread safe on many systems, 
it cannot be used to translate ``errno'' error codes
in to more readeable (for human beings) strings.</P
><P
>If you see strange ``errno: x'' error codes in your
logs, just use something like:

<PRE
CLASS="SCREEN"
>modxslt-perror x</PRE
>

to know which error verifyed during parsing. The value
of ``x'' is really system dependent, so, I cannot tell
you beforehand what the ``x'' errno error means on your
systme, unless you run modxslt-perror (which asks your
operative system what it means).</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN796"
>6.7.2. modxslt-config</A
></H3
><P
>modxslt-config can be used to query mod-xslt2 configure
and installation parameters. It is usually useful only
if you are encountering problems in using mod-xslt2 (problems
like inability to load libraries, linking failures...)
or if you are writing code for mod-xslt2 (to know the build
parameters to be used).</P
><P
>It can also be used to verify if mod-xslt2 is installed
on the system.</P
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x181.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x800.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>mod-xslt2 Setup and Usage</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Security considerations</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>