RE: [xsl] parsing a token list and finding a common ancestor in a tree

Subject: RE: [xsl] parsing a token list and finding a common ancestor in a tree
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 19 Jul 2007 20:49:13 +0100
> Assuming the list of identifiers is in the @wit attribute of 
> some <app> element, I think I can state my problem as: Find 
> all <node> elements that are the shared ancestors of all 
> <node> elements whose @n attribute value is one of the values 
> in the @wit token list. I tried, without success, several variants of:
> 
> <xsl:foreach select="//app">
>   <xsl:value-of select="//node[@n=tokenize(@wit, ' 
> ')]/ancestor::node"/> </xsl:foreach
> 
> This doesn't work, apparently because it looks for <node> 
> elements whose @n value is the entire tokenized list, instead 
> of any member of the list. 

No, it fails because you're looking at the @wit attribute of a <node>
element, not the @wit attribute of an <app> element. Try current()/@wit.

>Furthermore, even if it did work, I fear that it might get the union of
ancestors of *any* of the nodes in question, while I need the much more
restricted intersection of common ancestors shared by *all* the nodes.

Your fears are justified. Also, doing value-of on each ancestor doesn't look
very useful - what information are you actually trying to output?

Start with

<xsl:for-each select="//app">
  <xsl:variable name="nodes" select="//node[@n=tokenize(current()/@wit, '
')]"/>

then the common ancestors are:

select="$nodes/ancestor::node[every $n in $nodes satisfies
($n/ancestor::node intersect .)]"/>

then you can process these as you will...

This feels inefficient - we're getting all the ancestors of all the nodes,
eliminating duplicates, and then checking each one to make sure it's an
ancestor of all of them. But I can't think of anything better right now.

Micahel Kay
http://www.saxonica.com/

Current Thread