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 far. Cheers, Wendell Wendell Piez | http://www.wendellpiez.com XML | XSLT | electronic publishing Eat Your Vegetables _____oo_________o_o___ooooo____ooooooo_^ 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?