OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help

docbook-apps message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]

Subject: Re: [docbook-apps] help with xslt

2008/9/12 Sam Steingold <sds@gnu.org>:
> This would mean that I would have to write an xslt function mapping an array
> of integers #(11 1 2 1 2) to either sec_11-1-2-1-2 or 11_abab.
> How do I do that?
> To begin with, I don't even know how to iterate (or recurse) in xslt.
> I use xsltproc on linux.

I think any solution using standard XSLT 1.0 would be quite
convoluted, although probably still possible. There are options that
would make it easier and I'll outline a few approaches below.

In XSLT 1.0 (or rather XPath 1.0, which is where the expression
language comes from) there are no lists and for this problem you're
stuck with a prettly limited set of string manipulation functions.
There are functions that operate on node sets, which can be used a bit
like lists, but I don't think there's a way in standard XSLT 1.0 to
split up a string (like your ulink url attribute) into a node set.

In standard XSLT 1.0 the only string replacement function is
'translate' which operates on a per-character level, so you'll have
problems when your numbers have more than one digit. You should be
able to do something with the functions that extract substrings from a
string, though. I have an idea about how to do this but I won't
elaborate further unless you want me to because it's pretty
complicated and there are much easier solutions if you're able to go
beyond standard XSLT 1.0.

I think the easiest way would be to use EXSLT extensions
(www.exslt.org) if your XSLT processor supports them and you don't
mind depending on that. You say you're using xsltproc; the xsltproc on
my system does support a lot of EXSLT functions, but I'm not sure
which xsltproc version introduced this, or if it's a compile-time
option or something. If you run "xsltproc --dumpextensions" you can
see what functions your version supports.

Using a few EXSLT functions I got the following style sheet working
for the conversion from ulink url attributes like "sec_11-1-2-1-2" to
the "11_abab" format. It doesn't do everything you need - like
choosing between the two formats, handling links to chapters rather
than sections, or linking to the full CLHS URL - but hopefully you can
see the principle and how to do the rest.

<xsl:stylesheet version="1.0"
    extension-element-prefixes="dyn str">

  <xsl:template match="ulink[@role='clhs']">
    <xsl:variable name="subsection-names"
    <xsl:variable name="chapter"
        select="substring-before(substring-after(@url, 'sec_'), '-')"/>
    <xsl:variable name="source-subsections"
        select="substring-after(substring-after(@url, 'sec_'), '-')"/>
    <xsl:variable name="subsections"
        select="str:split($source-subsections, '-')"/>
    <xsl:variable name="target-subsections"
        select="dyn:map($subsections, 'substring($subsection-names, ., 1)')"/>
    <xsl:variable name="target"
        select="concat($chapter, '_', str:concat($target-subsections),
    <a href="{$target}">Link</a>


Another option would be to use XSLT 2.0, which (via XPath 2.0) has a
much wider range of built-in functions. But you'd have to use the
DocBook XSLT 2.0 style sheets, which I believe are still experimental,
and an XSLT 2.0 processor, of which there aren't many, possibly just
Saxon 9.

Hope this helps, please let me know if you'd like me to expand on any of this.


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]