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

Subject: RE: [xsl] Answers to review questions in "Beginning XSLT": Chapter 7
From: "Lars Huttar" <lars_huttar@xxxxxxx>
Date: Mon, 17 Mar 2003 11:02:23 -0600
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


Current Thread