[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Re: xhtml via xslt failure

Subject: Re: [xsl] Re: xhtml via xslt failure
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxx>
Date: Tue, 17 Dec 2013 10:52:13 -0500

Hi again,

It's funny. I was lying in bed last night and the little voice said
"preceding-sibling and following-sibling might not work for him". (The
little voice, with my apologies, assumed you are a 'him'.)

The following-sibling:: axis, like the preceding-sibling:: axis,
retrieves only nodes that are children of the same parent node
(siblings), so it won't work in cases where the logic has to examine
elements scattered throughout the document.

More broadly, most contingencies in designing XSLT depend on details
of the source data, which in turn may depend on constraints being
imposed on them in a schema (to provide predictability when source
data has not been seen yet). Accordingly, generalization can be
difficult, and unless we can nail down what the source data will look
like (its patterns and its variability), we are always guessing to
some extent.

So: your data has 'author' element siblings inside each 'book', so
within the scope of the book, assuming the authors are emitted in
document order, preceding-sibling:: and following-sibling:: will work.

Since your template here matches "bookstore/book", this appears to be
the case, so if the preceding-sibling:: and following-sibling:: axes
are not working, there is something else going on.

However, if you are not processing authors within the scope of the
book but rather within a wider scope (maybe all authors inside all
books at once), we have to do something different.

The position() function is useful, but a bit treacherous, as it
returns the position of a node in the sequence of nodes being
processed (the "context position"), which is not always what you think
it is, as it reflects the logical (sorted or unsorted) traversal order
in applying the entire stylesheet to the particular instance. (I say
'logical' because this is not necessarily a temporal ordering.)

Unfortunately I can't demonstrate your choices here in detail, from
your example, since you now appear to have a template rule
(xsl:template) inside your template, which makes no sense.

In general, however, I can state that two or three hours working
directly with a skilled XSLT programmer interactively would probably
teach you a great deal. Yours is (so far) a simple and straightforward
problem; but XSLT is very flexible and adaptable, and solutions
adapted to some other problem (not exactly yours) are likely to be
only more confusing, until you understand the principles.

If you can't arrange for any training, please read up on the XSLT
processing model, which is well documented in print and on line.

If things are still mysterious, go back to square one, and show us a
representative sample of your source data as well as your efforts so

Cheers, Wendell
Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables

On Tue, Dec 17, 2013 at 10:06 AM, e-letter <inpost@xxxxxxxxx> wrote:
> On 15/12/2013, e-letter <inpost@xxxxxxxxx> wrote:
> ...
>>            <book category=3D"WEB">
>>                     <title lang=3D"en">XQuery Kick Start</title>
>>                    <author>James McGovern</author>
>>                     <author>Per Bothner</author>
>>                     <author>Kurt Cagle</author>
>>                     <author>James Linn</author>
>>                     <author>Vaidyanathan Nagarajan</author>
>>                     <year>2003</year>
>>                     <price>49.99</price>
>>             </book>
> The stylesheet was edited to use the element conditional processing 'xsl:if':
> ...
> <xsl:template
>                 match="bookstore/book"
>                 >
>                 <p >
>                         <xsl:template
>                                 match="author"
>                                 >
>                                 <xsl:apply-templates/>
>                                 <xsl:if
>                                         test="following-sibling::author">
>                                         ,
>                                 </xsl:if>
>                                 <!--The following (from the specification example section 8.1)
> only works if the text to be separated by commas is contained within a
> single element, i.e. multiple authors listed in a single element
> 'author'. Does not work if each author contained in single element, ie
> <author>AB</author><author>CD</author>
>                                 <xsl:if
>                                         test="not(position()=last())">
>                                         ,
>                                 </xsl:if>-->
>                         </xsl:template>
>                         <xsl:apply-templates
>                                 select='author'
>                                 />
>                         <!--<xsl:value-of
>                         select="author"
>                         />-->
>                 </p>
>         </xsl:template>
> ...
> Why does the expression 'test="following-sibling::author"' fail?

Current Thread