OK, here are my answers for review questions from Chapter 5.
Intermingled are questions that I still have. If you have comments,
I'd be grateful for the feedback.
For now I'm omitting the questions themselves, since I don't yet have
explicit permission to copy them. (Jeni, would that be OK?)
Answers:
1. No nodes match the select pattern, so no templates get applied,
so there is no output for that apply-templates.
2. Use one template with match="Description//Film", and another with
match="Channel/Film". Or use match="Film" for one of them, and
the more specific match for the other.
3. This code produces a <div> element with contents as follows:
if there are Film children of the current node, they are processed
with xsl:apply-templates; otherwise, the message "No films..."
is included.
4. Rewriting of preceding code using <xsl:choose> instead of <xsl:if>:
<div>
<xsl:choose>
<xsl:when test="Film">
<xsl:apply-templates select="Film" />
</xsl:when>
<xsl:otherwise>
No films showing on this channel.
</xsl:otherwise>
</xsl:choose>
</div>
The advantage of the latter form is that if there are no Film
children of the current node, <xsl:apply-templates> doesn't get
evaluated. Also, it may be a little more clear to the human reader
that there are two mutually exclusive possibilities for the <div>
elements contents: the results of applying templates to "Film" children,
and the "No films..." message.
The advantage of the <xsl:if> form is that it is shorter, and for
that reason perhaps easier to read.
5. The given code inserts a 20x20 icon iff there is a flag attribute
on the current node. There is a specific icon for when the value
of the flag attribute is 'favorite', and another for when it is
'interesting', and a third for any other value. If the flag attribute
doesn't exist, no icon is inserted.
6. Rewriting of the above "as a sequence of <xsl:if> elements" instead of
using <xsl:choose>: (One could take "sequence" to mean "no nesting",
but that would hobble the <xsl:if> and I don't think that was the
intent of the question, so I'm going to nest them.)
<xsl:if test="@flag">
<xsl:if test="@flag = 'favorite'">
<img src="favorite.gif" alt="[Favorite]" width="20" height="20" />
</xsl:if>
<xsl:if test="@flag = 'interesting'">
<img src="interest.gif" alt="[Interest]" width="20" height="20" />
</xsl:if>
<xsl:if test="@flag != 'favorite' and @flag != 'interesting'">
<img src="flag.gif" alt="[Flagged]" width="20" height="20" />
</xsl:if>
</xsl:if>
The disadvantage of the <xsl:if> form is that if the flag attribute
exists, all three of the inner tests must be evaluated; whereas
in an <xsl:choose> element, when one test succeeds, the following
ones are ignored. Thus there is no need to repeat the comparisons
against 'favorite' and 'interesting'.
The advantage of the <xsl:if> form is that it is shorter. In this
case I've wrapped the comparisons of the value of @flag within a
test for the flag attribute's existence, thus saving work if the
attribute doesn't exist. This could also be done with a nested
<xsl:choose>, but would be more bulky because it would require
two nested elements, <xsl:choose> and <xsl:when>, as opposed to one
<xsl:if>.
7. test="Film/@year > 1950"
8. Film[starts-with(Title, 'Romeo')]
9. test="number()"
This converts the current node's value to a number, which is then
converted to true if non-zero, false if zero or NaN.
10. To test whether the current node's value is a number,
use test="number() or number() = 0" which gives the desired result.
Is there a simpler way?
I tried test="number() != NaN" but this was always false (Why? Is
NaN not recognized as the numeric constant? No, I just learned that
it's because NaN is not equal to itself! See the FAQ,
http://www.dpawson.co.uk/xsl/sect2/N5846.html);
test="number() != 'NaN'" was always true;
test="number() != number('NaN')" also was always true (see above,
NaN is not equal to itself);
test="string(number()) != 'NaN'" worked but this is not necessarily
simpler. (Btw I see from the FAQ that this is a standard way
to check whether a node's value is a number. There Jeni Tennison
also suggests test="@value <= 0 or @value > 0" or
test="number(@value) = number(@value)". However, these both rely
on properties of NaN that are not covered in ch. 5.)
Question: is there a way to represent the numeric constant NaN
in an expression? Apparently the unquoted NaN is not recognized
as such; I guess it's interpreted as "the value of the child element
named NaN."
OK, that's chapter 5. Thanks for your time and attention.
Feedback is appreciated.
Lars
-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com]On Behalf Of
Jeni Tennison
Sent: Tuesday, March 11, 2003 5:16 AM
To: Lars Huttar
Cc: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Answers to review questions in "Beginning XSLT"?
Hi Lars,
I've been working through Jeni Tennison's book, "Beginning XSLT". As
I answer the review questions at the end of each chapter, it would be
comforting to compare them with someone else's to make sure I hadn't
missed something important.
Does anybody have a collection of answers they've put together that
they'd be willing to share?
Anyone know of a forum or a web site anywhere where these answers are
posted and discussed? Seems like it would be a useful thing to have.
I think that you should feel free to post here, especially if there
are questions that you're not sure about or want to discuss the answer
to. Or there's the XSLT list on the p2p.wrox.com site; it looks like
Mike Kay answers a lot of queries there.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list