This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Closest ancestor with one of set of names
- To: "Wilcox, Paul" <Paul dot Wilcox at usa dot xerox dot com>
- Subject: [xsl] Re: Closest ancestor with one of set of names
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Fri, 24 Aug 2001 10:27:39 +0100
- CC: "'xsl-list at lists dot mulberrytech dot com'" <xsl-list at lists dot mulberrytech dot com>
- Organization: Jeni Tennison Consulting Ltd
- References: <B08661D21F0FD311A21A00805FC7D65002FA4160@usa0845ms1.svcdoc.mc.xerox.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
Hi Paul,
> I have a node stored in a variable, and a list of element names.
> The stored node is not the context node
>
> I need to find the node that meets these criteria:
> 1) name is in the list
> 2) is an ancestor of the stored node.
> 3) is the closest (most direct) ancestor of the stored node, from
> all ancestor nodes whose names (element names) are in the list,
You can find all ancestor elements of the node $NODE with:
$NODE/ancestor::*
When you use a variable reference at the beginning of a path then the
node(s) in that variable form the starting point for the path.
Assuming that the element names are given as the values of nodes in a
node set, held in the $NAMES variable, then you can find those
ancestor elements that have a name from that list with:
$NODE/ancestor::*[local-name() = $NAMES]
This works because if you compare a string (the local name) to a node
set, then the comparison is true if of the nodes have a value equal to
the string.
And you can find the closest one by looking at the first of those (the
ancestor:: axis is a reverse axis, so the first is the nearest
ancestor):
$NODE/ancestor::*[local-name() = $NAMES][1]
If the element names (e.g. FRONT and OPEN) are known to you, such that
they can be hardcoded in the stylesheet, then you could use something
like:
$NODE/ancestor::*[self::FRONT or self::OPEN][1]
This deals better with namespace issues than testing the local-name()
would.
If the element names are in a string (e.g. 'FRONT,OPEN') then you can
use contains() instead:
$NODE/ancestor::*[contains(concat(',', $NAMES, ','),
concat(',', local-name(), ','))][1]
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list