RE: [xsl] XPath to select based on attr = same attr of an ancestor

Subject: RE: [xsl] XPath to select based on attr = same attr of an ancestor
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 17 Jul 2008 15:33:22 +0100
> KH> foreign[@lang = ancestor::*[@lang][1]/@lang]
> MK> foreign[@lang = (ancestor::*/@lang)[last()]]

These are equivalent. 

(1) take the lang attribute of the first ancestor element (going upwards)
that has a lang attribute

(2) take all the lang attributes belonging to ancestor elements, then select
the last (going downwards).

> I would, however, like to understand why
>    foreign[@lang][ancestor::*[@lang]][1][ ./@lang = 
> ./ancestor::*[@lang][1]/@lang ] doesn't work. 

I've forgotten the details of the question, but I think the culprit is the
first [1]. The predicates [@lang] and [ancestor::*[@lang]] are harmless - if
the final predicate is true, then these predicates will also be true. But
the [1] means you only select the first <foreign> element for which these
predicates apply, which is not the case for the KH and MK expressions above.

> And am I right that the difference between the KH and MK 
> construc- tions are that the former is looking up the 
> ancestor axis for the first hit, whereas the latter is 
> looking down the ancestor axis for the last hit? Is one 
> "better" than the other in any significant way?

Probably the KH construction gives a better chance that the system will stop
its search of the ancestor axis early. On the other hand, it seems inelegant
having to access the @lang attribute of each ancestor twice.

Michael Kay

Current Thread