* * * * *

                    Technobabble technobabble technobabble

It took awhile, but I finally finished revamping [1] my homepage [2]. Perhaps
the major reason it took so long was my enthusiam for dealing with XSLT
(eXtensible Stylesheet Language Transformations) waxed and waned over the
past year. I got most of the way there by January of last year [3], but the
resulting XML (eXtensible Markup Language) files of my site were not that
well organized, and the XSLT file was a huge mess I could barely understand a
few hours after writing it; it doesn't help that XSLT is quite verbose.

Just how verbose?

Before I can get there, I have to be a bit verbose myself and explain that
the XML format I created looks a bit like:

> <site directory="/">
>   <section directory="writings/">
>     <subsection directory="murphy/"> … </subsection>
>     <subsection directory="hypertext/"> … </subsection>
>     …
>   </section>
>
>   <section directory="photos/">
>     <subsection directory="top10/"> … </subsection>
>     …
>   </section>
>   …
> </site>
>

The “site” (which is considered a “node”) is composed of several “sections”
(again a “node”), each of which is composed of “subsections” (yet another
type of “node”). Each node has a “directory” attribute, where the resulting
HTML files will reside. There's a bit more (like individual pages) but that's
enough to hopefully explain this wonderful bit of XSLT verbosity:

> <li> <a href="../{preceding-sibling::subsection[@listindex !=
> 'no'][position()=1]/attribute::directory}" title="{preceding-
> sibling::subsection[@listindex != 'no'][postition()=1]/child::title}">
> Previous </a> </li>
>

That's one line of XSLT code there (broken up over several so you won't have
to scroll all the way to the right). The nasty bit:

> {preceding-sibling::subsection[@listindex !=
> 'no'][position()=1]/attribute::directory}
>

comes into play when we're processing a template for a <subsection>, and in
English (as best as I can translate it is):

> Of the list of subsections that come prior to you in the current section,
> select those that do not have an attribute of listindex equal to “no” then
> select the first one in that list, then retrieve the value of the directory
> attribute.
>

Because if you don't specify the position(), you get the last one (which in
this case would be the first subsection in the section that does not have the
listindex attribute set to “no”) not the first node (even though technically
it's the last node in the list of preceding nodes, and following-sibling
works as expected—which makes a perverse type of sense in a Zen like way).
Got it? Good. Because I barely grok it myself.

What it generates is something like:

> <li> <a href="‥/murphy/" title="Murphy's Law"> Previous </a> </li>
>

Which is a link (within an HTML (HyperText Markup Language) list) to the
previous subsection.

That line comes in the middle of a section of XSLT code that, loosely
translated into pseudocode, reads:

> when in a subsection
>   choose
>     when listing nodes in order
>       if there exists a following node that is not hidden
>         print "... Next ... "
>       end-if
>       if there exists a  preceding node that is not hidden
>         print "... Previous ... "
>       end-if
>     end-when
>     ...
>   end-choose
> end-when
>

Only not as succinctly (I'm viewing the code in a window 144 characters wide,
and each line still wraps around). COBOL (COmmon Business Orientated
Language) is terse compared to XSLT. And imaging writing about a thousand
lines like that.

I did give serious consideration to using something else other than XSLT to
convert my site from XML to HTML, but the alternatives weren't much better; I
could have used Perl and XML::Parser, but then I would have to explicitely
crawl the resulting tree for appropriate nodes (the addressing methods in
XSLT, while verbose and sometimes inexplicably odd, do make it easy to grab
nodes) and the logic for generating the pages, but code to dump out nodes
verbatim. For instance, I have sections like:

> <body>
> ... HTML formatted as XML ...
> </body>
>

and to avoid having to write endless templates for things like <P> and
<BLOCKQUOTE>, in XSLT, I just dump such sections out like:

> <xsl:copy-of select="./node()"/>
>

Which does a literal copy of all the children nodes of the current node. If I
were to use Perl, I would have to code this myself (the same consideration
for using any other programming language with an XML parser really). Kind of
six of one, half-dozen the other.

And seeing how I already had written a few thousand lines of XSLT (previous
versions, revisions, etc., etc.) I decided to stick with what I started and
see it through.

But now that I have this massive XSLT file, I don't really have to mess with
it anymore. I can now just add content to the XML file that represents my
site (I was able to add a photo gallery in about fifteen minutes of work,
mostly spent typing the descriptions, without having to worry about adding
navigation and images), then regenerate the site.

And speaking of navigation—back when I last overhauled my site, it was to add
navigation links (thanks to Eve, who convinced me to add them), about half
the XSLT I wrote was to support the navigation links (as you can see from the
examples above). I have an extensive array of navigation links [4] mostly
hidden behind the <LINK> tags; if you have Mozilla [5], you can see them by
enabling the “Site Navigation Bar” (View → Show/Hide → Site Navigation Bar).
Quite a bit of work for something of perhaps dubious value? We'll see …

[1] gopher://gopher.conman.org/0Phlog:2002/10/21.1
[2] http://www.conman.org/people/spc/
[3] gopher://gopher.conman.org/0Phlog:2003/01/16.2
[4] http://www.conman.org/people/spc/
[5] http://www.mozilla.org/

Email author at [email protected]