xsl-list
[Top] [All Lists]

RE: Answers to review questions in "Beginning XSLT": Chapter 7

2003-03-17 10:02:23
Hello Jeni,

Thanks for going through those answers and responding.

4. Assuming that the prefix tv is associated with the namespace
http://www.example.com/TVGuide within the stylesheet, what kinds of
elements do the following expressions select?

Answer:

Program -- any child element of . named "Program" in no namespace
tv:* -- any child element node of . in the 
http://www.example.com/TVGuide
  namespace
tv:Program -- any child element of . named "Program" in the
  http://www.example.com/TVGuide namespace.
*[name() = 'Program'] -- same as just Program

Not quite. When you use the name() function, what you get depends on
the prefix that was used in the source document.  If, in the source
document, the http://www.example.com/TVGuide namespace is the default
namespace, as in:

  <Program xmlns="http://www.example.com/TVGuide";>
    ...
  </Program>

then name() = 'Program' might return true for that element.

Oops, I missed that.  Thanks.
In other words, select="Program" is quite different from
select="*[name() = 'Program']", as the former says "no namespace"
and the latter says "the default namespace in the source doc."

I say might because if the namespace is *also* declared with the
prefix 'tv', as in:

  <Program xmlns="http://www.example.com/TVGuide";
           xmlns:tv="http://www.example.com/TVGuide";>
    ...
  </Program>

then the processor is free to return either "Program" or "tv:Program".
It doesn't matter what prefix was actually used on the element, only
what prefixes are declared for the element's namespace.

This makes sense; but then don't you think the definition on p. 247 is a bit 
misleading?

  "name() returns the full name of the element or attribute as given
  in the source document, including the prefix if there is one."

Anyway, the revised answers:
 *[name() = 'Program'] -- a child element of . named Program that is in the
   default namespace (that is in scope at this point in the source document)
   (or no namespace if there is no default).
 *[starts-with(name(), 'tv:')] -- a child element of . that is in the namespace
   associated with the tv: prefix in the source document.
 *[name() = 'tv:Program'] -- a child element of . named Program that is
   in the namespace associated with the tv: prefix in the source document.


Excellent. In general I'd avoid using count() if you can because naive
processors are likely to collect all the nodes that the path selects
so that they can be counted. If you use:

  preceding-sibling::*[name() = $name] or
  following-sibling::*[name() = $name]

then a processor can stop looking once it's found the first preceding
or following sibling with the same name (and doesn't even have to look
at the following siblings if it finds a preceding sibling with the
same name).

Good point.  Since we're not really interested in the total number,
it makes more sense to just test for existence of siblings.

Thanks again for your help.

Lars


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list