Jeni wrote:
Lars wrote:
2. What format can the values of ID attributes take?
Answer:
They have to be XML Names, which means they must start with a
letter, underscore, or colon, and contain only "alphanumeric"
characters (which include '.' | '-' | '_' | ':' plus other similar
punctuation in Unicode). In particular, no spaces are allowed.
There are a couple of things here. You say "plus other similar
punctuation in Unicode". Actually, XML names can only include the
punctuation characters you list: '.', '-', '_' and ':'.
Hmm. I'm looking at the W3C XML 1.0 spec (Second Edition). Admittedly
it does say at first, "Definition: A Name is a token beginning with a
letter or one of a few punctuation characters, and continuing with letters,
digits, hyphens, underscores, colons, or full stops, together known as name
characters." However, that's apparently a simplified summary...
the production rules for Name and NameChar, shown a couple of paragraphs
later,
Name ::= (Letter | '_' | ':') (NameChar)*
NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar |
Extender
make it clear that certain other Unicode characters are allowed, e.g. diacritics
(such as #x0300) and punctuation akin to hyphens (such as #x00B7).
The ':'
character should not be used in IDs nowadays because the Namespaces in
XML Rec. stated that you should use NCNames instead of full XML Names.
NCNames (non-colonised names) can't contain a colon.
Good point.
7. Construct a stylesheet that groups <Film> elements by
their <Year>
children and by their rating attributes.
Answer:
That looks good (I assume it worked!). Another challenge is a
stylesheet that will group first by Year and then (within that) by
rating. [I think that's what I meant by the question, but I admit that
it's not worded clearly.]
You don't want much, do you? :-)
Well, that would make sense given that the chapter takes pains to
explain multi-level grouping. Guess I chose to interpret the question
the lazy way. :-)
OK, here's the revised stylesheet.
You're right of course, it was good to have the exercise of putting this
kind of grouping into practice. My brain feels like it's been stretched.
Lars
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="filmsByYear" match="Film" use="Year" />
<xsl:key name="filmsByYearAndRating" match="Film" use="concat(Year, '+',
@rating)" />
<xsl:template match="/">
<html>
<head>
<style>
.filmname {
font-style: italic
}
</style>
</head>
<body>
<h1>Films, by Year</h1>
<xsl:apply-templates select="Films/Film[generate-id() =
generate-id(key('filmsByYear', Year)[1])]"
mode="YearList">
<xsl:sort select="Year" data-type="number"/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="Film" mode="YearList">
<h2><xsl:value-of select="Year" /></h2>
<xsl:apply-templates select="key('filmsByYear', Year)
[generate-id() =
generate-id(key('filmsByYearAndRating',
concat(Year, '+',
@rating))[1])]"
mode="YearRatingList">
<xsl:sort select="@rating" data-type="number" order="descending" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Film" mode="YearRatingList">
<h3><xsl:value-of select="@rating" /> stars</h3>
<xsl:apply-templates select="key('filmsByYearAndRating',
concat(Year, '+', @rating))"
mode="Detail">
<xsl:sort select="Name" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Film" mode="Detail">
<p>
<span class="filmname"><xsl:value-of select="Name" /></span>,
<xsl:value-of select="Year" />. Stars:
<xsl:value-of select="@rating" />
</p>
</xsl:template>
</xsl:stylesheet>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list