This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Documenting xsl code.


Apologies that I didn't respond to this thread earlier, I was moving half-way
around the world ...

I was glad to see that some people were thinking of literate programming (and
even FunnelWeb, a program I worked on myself for a while) when considering how
to add documentation to XSLT stylesheets.  While a Javadoc-style solution may
be OK for some uses, Javadoc is something different to a literate program. 
Javadoc is need for hyperlinking between lots of simple items in a large API,
but falls far short of a good literate program for describing how a piece of
code works.  XSLT templates can be very difficult to interpret for beginners,
so every bit of explanation is a very good thing.

I have been working (albeit slowly) on a system for doing literate programming
from XML source documents.  I call the tool "xmLP"; it is still at an "alpha"
stage, but nonetheless does both "weave" (generate documentation) and "tangle"
(assemble the product source files).  At the bottom of this message is a sample
of the documentation produced (currently) by "xmLP".  This is based heavily on
my FunnelWeb experience.

I don't have the "xmLP" sources on the Web at present (give me a week or two),
but if you are really interested, reply to me early by e-mail and I will send
you a copy.  There are just two XSLT stylesheets, one to tangle, one to weave. 
They work with Xalan, and haven't been tested as yet with other XSLT engines.

I would be interested to get your replies as to what you do/don't like about
the "xmLP" documentation (do remember that what is attached is a rather potted
example, so forgive me that the content is flimsy).

	Cheers,
			Tony.

PS If you have questions about literate programming & XML, you could do worse
than join the (very low volume) "xml-litprog-l" list:
http://www.egroups.com/group/xml-litprog-l

==== xmLP-xslt.html ====
<HTML xmlns:lp="http://www.litprog.org/xmLP/alpha-2000-04-09/">
<HEAD>
  <TITLE>A Gentle Intro to XSLT</TITLE>
<LINK xmlns="http://www.w3.org/TR/REC-html40" TYPE="text/css" SRC="xmLPdoc.css"
REL="stylesheet" HREF="xmLPdoc.css"></HEAD>

<BODY>

<H1>
  A Gentle Introduction to XSL Transformations (XSLT)
</H1>
<HR>


<H1>Table of Contents</H1>
<H2 xmlns="http://www.w3.org/TR/REC-html40"><A href="#1%20About%20%22xmLP%22">1
About "xmLP"</A></H2><H2 xmlns="http://www.w3.org/TR/REC-html40"><A
href="#2%20Overview">2 Overview</A></H2><H2
xmlns="http://www.w3.org/TR/REC-html40"><A
href="#3%20A%20Sample%20XML%20File">3 A Sample XML File</A></H2><H2
xmlns="http://www.w3.org/TR/REC-html40"><A
href="#4%20Generating%20HTML%20Output">4 Generating HTML Output</A></H2><H2
xmlns="http://www.w3.org/TR/REC-html40"><A href="#5%20Running%20%22xmLP%22">5
Running "xmLP"</A></H2><H2 xmlns="http://www.w3.org/TR/REC-html40"><A
href="#6%20List%20of%20Macros">6 List of Macros</A></H2><H2
xmlns="http://www.w3.org/TR/REC-html40"><A href="#7%20List%20of%20Files">7 List
of Files</A></H2>
<HR>


<H1 xmlns="http://www.w3.org/TR/REC-html40"><A NAME="1%20About%20%22xmLP%22">1
About "xmLP"</A></H1>
<P>
This document is a literate program created using the prototype
literate programming tool "xmLP".  Literate programming
tools allow code and documentation to be interspersed in the one file.
For "xmLP", the source file is written in XML, and the
documentation is created in XML or HTML using the instructions in an
XSL transformation file.  Code sections look like the following:
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[1]PLmx"></A><DL><DT><EM><lp:name>Example code definition</lp:name>
[1] =</EM></DT><DD><PRE>&lt;code, typeset differently from descriptive
text&gt;</PRE></DD></DL><H5><BR>This macro is NEVER invoked.</H5></DIV>

<P>
Code sections can also be additive, as with the two following examples:
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[2]PLmx"></A><DL><DT><EM><lp:name>Additive code definition
example</lp:name> [2] +=</EM></DT><DD><PRE>&lt;first part of the
code&gt;</PRE></DD></DL><H5>This macro is defined in definitions <A
HREF="#xmLP[2]PLmx">2</A> <A HREF="#xmLP[3]PLmx">3</A>.<BR>This macro is NEVER
invoked.</H5></DIV>

<P></P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[3]PLmx"></A><DL><DT><EM><lp:name>Additive code definition
example</lp:name> [3] +=</EM></DT><DD><PRE>&lt;second part of the
code&gt;</PRE></DD></DL><H5>This macro is defined in definitions <A
HREF="#xmLP[2]PLmx">2</A> <A HREF="#xmLP[3]PLmx">3</A>.<BR>This macro is NEVER
invoked.</H5></DIV>


<H1 xmlns="http://www.w3.org/TR/REC-html40"><A NAME="2%20Overview">2
Overview</A></H1>
<P>
The XSL transformation language (XSLT) is a scripting language that transforms
XML files
into XML, HTML, or text, based on patterns.  Whenever a pattern is recognised,
a matching
transformation is performed.  This differs from more traditional procedural
languages,
where actions are performed one after the other in a more deterministic manner.
Besides XSLT, other existing pattern matching languages are Prolog and
Mathematica.
</P>

<P>
All of this is a bit vague without a concrete example, so let us start with
one.
</P>



<H1 xmlns="http://www.w3.org/TR/REC-html40"><A
NAME="3%20A%20Sample%20XML%20File">3 A Sample XML File</A></H1>
<P>
For this document, the following sample XML file will be used.  It is an RDF
file
(<A xmlns="http://www.w3.org/TR/REC-html40"
HREF="http://www.w3.org/TR/REC-rdf-syntax">Resource Description Framework</A>)
which describes the properties (name/value pairs) of some objects.  Be assured
that no understanding of RDF is required to understand this document.  However,
it will
be assumed that the RDF properties are to be displayed using HTML, which is not
an
unlikely scenario.
</P>

<P>
Without further ado, the sample XML (RDF) is as follows:
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-file-def"><A
NAME="xmLPfile[1]elifPLmx"></A><DL><DT><EM>animals.rdf [1]
=</EM></DT><DD><PRE>&lt;?xml version="1.0"?&gt;

&lt;rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:s="http://dummy.org/xmLP-RDF-sample"
&gt;
  &lt;rdf:Description about="http://dummy.org/animal/octopus"&gt;
    &lt;s:Name&gt;Octopus&lt;/s:Name&gt;
    &lt;s:LegCount&gt;8&lt;/s:LegCount&gt;
    &lt;s:Habitat&gt;Sea &amp;amp; Ocean&lt;/s:Habitat&gt;
    &lt;s:Carnivore&gt;True&lt;/s:Carnivore&gt;
  &lt;/rdf:Description&gt;

  &lt;rdf:Description about="http://dummy.org/animal/elephant"&gt;
    &lt;s:Name&gt;Elephant&lt;/s:Name&gt;
    &lt;s:LegCount&gt;4&lt;/s:LegCount&gt;
    &lt;s:Habitat&gt;Africa &amp;amp; Asia&lt;/s:Habitat&gt;
    &lt;s:Carnivore&gt;False&lt;/s:Carnivore&gt;
  &lt;/rdf:Description&gt;
&lt;/rdf:RDF&gt;</PRE></DD></DL><H5>This is an output file.</H5></DIV>

<P>
The XML (RDF) sample contains the following information:
</P>
<OL>
  <LI>an octopus has 8 legs, lives in the sea and ocean, and is a
carnivore;</LI>
  <LI>an elephant has 4 legs, lives in Africa and Asia, and is not a
carnivore.</LI>
</OL>


<H1 xmlns="http://www.w3.org/TR/REC-html40"><A
NAME="4%20Generating%20HTML%20Output">4 Generating HTML Output</A></H1>
<P>
To generate HTML output, the XSLT stylesheet must contain an appropriate
"<KBD>xsl:output</KBD>" tag.
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[4]PLmx"></A><DL><DT><EM><lp:name>HTML Output Tag</lp:name> [4]
=</EM></DT><DD><PRE>&lt;xsl:output method="html"
indent="no"/&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P>
Assume that the properties of each object (animal) is to be put into a separate
HTML
table.  In the RDF file, each separate object has a separate
"<KBD>rdf:Description</KBD>"
tag, so this can be used as the pattern to generate the HTML "<KBD>TABLE</KBD>"
tag.  A
suitable XSLT "<KBD>xsl:template</KBD>" pattern is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[5]PLmx"></A><DL><DT><EM><lp:name>rdf:Description template</lp:name>
[5] =</EM></DT><DD><PRE>&lt;xsl:template match="rdf:Description"&gt;
  &lt;P&gt;
  &lt;TABLE BORDER="2" WIDTH="60%"&gt;
    &lt;xsl:apply-templates/&gt;
  &lt;/TABLE&gt;
  &lt;/P&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P>
This template (pattern) does the following: when and if an
"<KBD>rdf:Description</KBD>"
tag is encountered, it is replaced by an HTML "<KBD>TABLE</KBD>" tag (inside a
"<KBD>P</KBD>" tag.  The XSLT "<KBD>xsl:apply-templates</KBD>" tag indicates
that pattern
matching should be done recursively on anything between
"<KBD>&lt;rdf:Description&gt;</KBD>" and its matching closing tag
"<KBD>&lt;/rdf:Description&gt;</KBD>".  This is very important; if the
"<KBD>xsl:apply-templates</KBD>" tag was left out of the template, all that
would be
generated in the output HTML file would be
"<KBD>&lt;TABLE&gt;&lt;/TABLE&gt;</KBD>", i.e.
a rather boring table with neither rows nor columns.
</P>

<P>
As each property is encountered, a table row should be generated for it showing
its name
and its value.  A simple (but not scalable) way to deal with this is to create
a template
for each property.  For the "<KBD>Name</KBD>" property, a suitable template
(pattern) is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[6]PLmx"></A><DL><DT><EM><lp:name>s:Name template</lp:name> [6]
=</EM></DT><DD><PRE>&lt;xsl:template match="s:Name"&gt;
  &lt;TR&gt;
    &lt;TH WIDTH="33%"&gt;Name&lt;/TH&gt;
    &lt;TD WIDTH="*"&gt;&lt;xsl:value-of select="text()"/&gt;&lt;/TD&gt;
  &lt;/TR&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P>
This creates a heading column with the name of the property ("Name"), and a
normal column
with the value of the property.  The "<KBD>xsl:value-of</KBD>" tag is used to
get a
value from the source document, and "<KBD>text()</KBD>" returns the text of the
<EMPH>current</EMPH> tag.  As the template is executing, the
<EMPH>current</EMPH> tag is
"<KBD>s:Name</KBD>", which is exactly what we want the text of.
</P>

<P>
The other property tags are handled similarly.
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[7]PLmx"></A><DL><DT><EM><lp:name>s:LegCount template</lp:name> [7]
=</EM></DT><DD><PRE>&lt;xsl:template match="s:LegCount"&gt;
  &lt;TR&gt;
    &lt;TH&gt;Leg Count&lt;/TH&gt;
    &lt;TD&gt;&lt;xsl:value-of select="text()"/&gt;&lt;/TD&gt;
  &lt;/TR&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P></P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[8]PLmx"></A><DL><DT><EM><lp:name>s:Habitat template</lp:name> [8]
=</EM></DT><DD><PRE>&lt;xsl:template match="s:Habitat"&gt;
  &lt;TR&gt;
    &lt;TH&gt;Habitat&lt;/TH&gt;
    &lt;TD&gt;&lt;xsl:value-of select="text()"/&gt;&lt;/TD&gt;
  &lt;/TR&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P></P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[9]PLmx"></A><DL><DT><EM><lp:name>s:Carnivore template</lp:name> [9]
=</EM></DT><DD><PRE>&lt;xsl:template match="s:Carnivore"&gt;
  &lt;TR&gt;
    &lt;TH&gt;Carnivore?&lt;/TH&gt;
    &lt;TD&gt;&lt;xsl:value-of select="text()"/&gt;&lt;/TD&gt;
  &lt;/TR&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P>
Finally, the HTML page will need the usual "<KBD>HTML</KBD>",
"<KBD>HEAD</KBD>",
and "<KBD>BODY</KBD>" tags to make it complete, and these can be added by
adding
a template for the root of the source document, which is represented by a
single
forward slash ("<KBD>/</KBD>"). 
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[10]PLmx"></A><DL><DT><EM><lp:name>Document root template</lp:name>
[10] =</EM></DT><DD><PRE>&lt;xsl:template match="/"&gt;
  &lt;HTML&gt;
  &lt;HEAD&gt;
    &lt;TITLE&gt;RDF Properties&lt;/TITLE&gt;
  &lt;/HEAD&gt;
  &lt;BODY&gt;
    &lt;xsl:apply-templates/&gt;
  &lt;/BODY&gt;
  &lt;/HTML&gt;
&lt;/xsl:template&gt;</PRE></DD></DL><H5><BR>This macro is invoked in files <A
HREF="#xmLPfile[2]elifPLmx">2</A>.</H5></DIV>

<P>
Note that an XSLT "<KBD>xsl:apply-templates</KBD>" tag is required to make sure
that
the other templates are called as their patterns are encountered.
</P>

<P>
Finally, the XSLT stylesheet is assembled as follows:
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-file-def"><A
NAME="xmLPfile[2]elifPLmx"></A><DL><DT><EM>rdf2html1.xsl [2]
=</EM></DT><DD><PRE>&lt;?xml version="1.0"?&gt;

&lt;xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:lp="http://www.litprog.org/xmLP/alpha-2000-04-09/"
  xmlns="http://www.w3.org/TR/REC-html40"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:s="http://dummy.org/xmLP-RDF-sample"
  version="1.0"
&gt;

<I><A HREF="#xmLP[4]LPmx">HTML Output Tag</A></I>

<I><A HREF="#xmLP[10]LPmx">Document root template</A></I>

<I><A HREF="#xmLP[5]LPmx">rdf:Description template</A></I>

<I><A HREF="#xmLP[6]LPmx">s:Name template</A></I>

<I><A HREF="#xmLP[7]LPmx">s:LegCount template</A></I>

<I><A HREF="#xmLP[8]LPmx">s:Habitat template</A></I>

<I><A HREF="#xmLP[9]LPmx">s:Carnivore template</A></I>

&lt;/xsl:stylesheet&gt;</PRE></DD></DL><H5>This is an output file.</H5></DIV>


<H1 xmlns="http://www.w3.org/TR/REC-html40"><A
NAME="5%20Running%20%22xmLP%22">5 Running "xmLP"</A></H1>
<P>
To run "xmLP", you need an XSLT engine.  In particularly, "xmLP" has only been
tested
with the Java version of Apache's "Xalan" XSLT engine (formerly "LotusXSL"). 
To run
Xalan, your Java <KBD>CLASSPATH</KBD> should contain "<KBD>xalan.jar</KBD>" and
"<KBD>xerces.jar</KBD>".  Xalan is then invoked using
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-macro-def"><A
NAME="xmLP[11]PLmx"></A><DL><DT><EM><lp:name>Xalan</lp:name> [11]
M=</EM></DT><DD><PRE>java
org.apache.xalan.xslt.Process</PRE></DD></DL><H5><BR>This macro is invoked in
macros <A HREF="#xmLP[12]PLmx">12</A> <A HREF="#xmLP[13]PLmx">13</A> <A
HREF="#xmLP[14]PLmx">14</A> <A HREF="#xmLP[15]PLmx">15</A>.</H5></DIV>

<P>
and so the full command line is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[12]PLmx"></A><DL><DT><EM><lp:name>Xalan command line</lp:name> [12]
=</EM></DT><DD><PRE><I><A HREF="#xmLP[11]LPmx">Xalan</A></I> -IN
&lt;xml-source&gt; -XSL &lt;xsl-stylesheet&gt; -OUT
&lt;output-file&gt;</PRE></DD></DL><H5><BR>This macro is NEVER
invoked.</H5></DIV>

<P>
To generate this documentation, the command is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[13]PLmx"></A><DL><DT><EM><lp:name>Documentation command
line</lp:name> [13] =</EM></DT><DD><PRE><I><A
HREF="#xmLP[11]LPmx">Xalan</A></I> -IN xmlp-xslt.xml -XSL xmLPweave.xsl -OUT
xmlp-xslt.html</PRE></DD></DL><H5><BR>This macro is NEVER invoked.</H5></DIV>

<P>
To generate the RDF file and the stylesheet which generates a matching HTML
page, the
command is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[14]PLmx"></A><DL><DT><EM><lp:name>Product files command
line</lp:name> [14] =</EM></DT><DD><PRE><I><A
HREF="#xmLP[11]LPmx">Xalan</A></I> -IN xmlp-xslt.xml -XSL
xmLPtangle.xsl</PRE></DD></DL><H5><BR>This macro is NEVER invoked.</H5></DIV>

<P>
To run the product XSLT stylesheet on the RDF file and produce the matching
HTML page,
the command is
</P>

<DIV xmlns="http://www.w3.org/TR/REC-html40" CLASS="xmlp-z-macro-def"><A
NAME="xmLP[15]PLmx"></A><DL><DT><EM><lp:name>RDF sample command line</lp:name>
[15] =</EM></DT><DD><PRE><I><A HREF="#xmLP[11]LPmx">Xalan</A></I> -IN
animals.rdf -XSL rdf2html1.xsl -OUT animals.html</PRE></DD></DL><H5><BR>This
macro is NEVER invoked.</H5></DIV>

<P>
That, then, is a very quick and potted introduction to how XSLT stylesheets are
constructed.  There are many powerful features that have not been mentioned
here,
so keep reading about XSLT and you will discover what a useful tool it is.
</P>

<HR>

<H1 xmlns="http://www.w3.org/TR/REC-html40"><A NAME="6%20List%20of%20Macros">6 List of
Macros</A></H1>
<OL xmlns="http://www.w3.org/TR/REC-html40"><LI><A href="#xmLP[1]PLmx">Example
code definition</A> [never invoked]</LI><LI><A href="#xmLP[2]PLmx">Additive
code definition example</A> [#1/2] [never invoked]</LI><LI><A
href="#xmLP[3]PLmx">Additive code definition example</A> [#2/2] [never
invoked]</LI><LI><A href="#xmLP[4]PLmx">HTML Output Tag</A></LI><LI><A
href="#xmLP[5]PLmx">rdf:Description template</A></LI><LI><A
href="#xmLP[6]PLmx">s:Name template</A></LI><LI><A
href="#xmLP[7]PLmx">s:LegCount template</A></LI><LI><A
href="#xmLP[8]PLmx">s:Habitat template</A></LI><LI><A
href="#xmLP[9]PLmx">s:Carnivore template</A></LI><LI><A
href="#xmLP[10]PLmx">Document root template</A></LI><LI><A
href="#xmLP[11]PLmx">Xalan</A></LI><LI><A href="#xmLP[12]PLmx">Xalan command
line</A> [never invoked]</LI><LI><A href="#xmLP[13]PLmx">Documentation command
line</A> [never invoked]</LI><LI><A href="#xmLP[14]PLmx">Product files command
line</A> [never invoked]</LI><LI><A href="#xmLP[15]PLmx">RDF sample command
line</A> [never invoked]</LI></OL>

<HR>

<H1 xmlns="http://www.w3.org/TR/REC-html40"><A NAME="7%20List%20of%20Files">7
List of Files</A></H1>
<OL xmlns="http://www.w3.org/TR/REC-html40"><LI><A
href="#xmLPfile[1]elifPLmx">animals.rdf</A></LI><LI><A
href="#xmLPfile[2]elifPLmx">rdf2html1.xsl</A></LI></OL>

</BODY>
</HTML>
==== xmLPdoc.css ====
BODY {
  background-color:white;
  text-color:black;
}
H1 {
  text-align:center;
}
H2, H3, H4, H5, ADDRESS {
  text-align:left;
}
H1, H2 {
  color:darkgreen;
}
H3, H4, B {
  color:darkred;
}
DT {
  font-style:bold;
}
H1 {
  font-size:24pt;
}
H2 {
  font-size:18pt;
}
H3 {
  font-size:16pt;
}
H4 {
  font-size:14pt;
}
P, PRE, UL, OL, DL {
  font-size:12pt;
}
.xmlp-macro-def, .xmlp-z-macro-def, .xmlp-file-def {
  border-color:darkblue;
  border-style:ridge;
  border-width:2;
  padding:20;
}
.xmlp-macro-def {
  background-color:lightyellow;
}
.xmlp-z-macro-def {
  background-color:lightblue;
}
.xmlp-file-def {
  background-color:pink;
}
.xmlp-error {
  color:red;
}
.xmlp-warning {
  color:orange;
}
==== end ====

========
Anthony B. Coates
XML Architecture & Design
Research and Standards Group
Reuters Plc, London.
tony.coates@reuters.com
========

-----------------------------------------------------------------
        Visit our Internet site at http://www.reuters.com

Any views expressed in this message are those of  the  individual
sender,  except  where  the sender specifically states them to be
the views of Reuters Ltd.


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]