Re: [xsl] Re: xhtml via xslt failure

Subject: Re: [xsl] Re: xhtml via xslt failure
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxx>
Date: Mon, 16 Dec 2013 17:01:53 -0500
Hi,

On Mon, Dec 16, 2013 at 3:38 PM, e-letter <inpost@xxxxxxxxx> wrote:
> On 15/12/2013, e-letter <inpost@xxxxxxxxx> wrote:
...
> According to the specification the above transformation can be
> achieved using either element 'apply-templates' or element 'value-of'.

To what specification do you refer? Certainly, the XSLT Recommendation
(neither versions 1.0 nor 2.0) say this, since the two instructions do
not do the same thing.

> Why is it that when the element 'value-of' in the stylesheet above is
> substituted for the element 'apply-templates', the result is a
> truncation of the third line in the xhtml file, i.e. to:
>
> ...
> <p>James McGovern</p>
> ...

Under XSLT 1.0, value-of select="./author" (an abbreviation for
select="self::node()/child::author") will copy the value of the first
'author' element child (only) of the context into the result. (Under
XSLT 2.0 it will copy the values of all 'author' element children.)
This is usually not what you want, inasmuch as there may be more than
author element.

apply-templates select="author", in contrast, selects all author
element children and applies templates to them. As you have not
provided an author, the built-in template for elements will be used;
it applies templates to the element contents, which results (unless
you intervene to change this behavior) in the element's data contents
(text node descendants) being copied into the result.

Indeed, using xsl:value-of instead of xsl:apply-templates in such a
case, and expecting them to emit the same results, is a good
indication that the author of the code does not understand XSLT. They
will often emit the same results, but not always, and the difference
(when they do and don't) is crucial.

(And using "./author" instead of the simpler and more efficient
"author" is an indication that the author doesn't know XPath very well
yet. :-)

> Also, it it possible to add whitespace  and punctuation to the xhtml output, eg.
>
> ...
> <p>James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan
> Nagarajan</p>

Yes, it is possible. In fact, to do so, use a template matching 'author':

<xsl:template match="author">
  <!-- provide a comma if not the first author -->
  <xsl:if test="preceding-sibling::author">, </xsl:if>
  <!-- process the element contents -->
  <xsl:apply-templates/>
</xsl:template>

(Of course this solution is available only if you apply templates to
the 'author' elements instead of using value-of.)

In XSLT 2.0 you could skip the templates and say

<xsl:value-of select="author" separator=", "/>

But I would recommend this only if 'author' elements never have any
structure (markup) but only text.

You also did not fix the namespace problem I pointed out this morning,
which has not bitten you yet, but is likely to do so as your XSLT
becomes more complex. Keep an eye out for xmlns="" turning up in your
results where you don't want them.

Cheers, Wendell

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

Current Thread