[xsl] Re: RE: Finding corresponding node in structurally identical sibling tree?

Subject: [xsl] Re: RE: Finding corresponding node in structurally identical sibling tree?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 26 Apr 2002 09:46:50 -0700 (PDT)
> > I need to quickly find the matching node to the current node
> > which is in a parallel branch with identical structure to the
> > branch I'm operating in. It seems like this should be really
> > simple, but the only solution I can come up with is
> > a recursive template to assemble the name of the path from
> > the branch tag down, and then compare that against the result
> > from the same template for each node in the second tree. The
> > trees may be of arbitrary depth. Any other ideas?
> 
> Depends what you mean by "quickly", but you could try:
> 
> <xsl:variable name="branch1index"
> select="count(/example/branch1/preceding::node())"/>
> <xsl:variable name="thisindex" select="count(preceding::node())"/>
> 
> select="/example/branch2/descendant::node[$thisindex -
$branch1index]"


Using only the count of preceding nodes is not sufficient to uniquely
determine a node. The number of ancestor nodes is also necessary.

Therefore, one XPath expression that returns the required corresponding
node is:

$br2//node()
  [count(preceding::node()) - $br2PrecIndex = $thisRelPrecIndex 
 and 
  count(ancestor::node()) - $br2AncIndex = $thisRelAncIndex
  ]

where there are the following variable definitions:

<xsl:variable name="br1" select="/*/branch1"/>
<xsl:variable name="br2" select="/*/branch2"/>

<xsl:variable name="thisPrecIndex" select="count(preceding::node())"/>
<xsl:variable name="thisAncIndex" select="count(ancestor::node())"/>

<xsl:variable name="br1PrecIndex" 
              select="count($br1/preceding::node())"/>
<xsl:variable name="br1AncIndex"
select="$br1/count(ancestor::node())"/>

<xsl:variable name="br2PrecIndex" 
              select="count($br2/preceding::node())"/>
<xsl:variable name="br2AncIndex"
select="$br2/count(ancestor::node())"/>

<xsl:variable name="thisRelPrecIndex" 
              select="$thisPrecIndex - $br1PrecIndex"/>
<xsl:variable name="thisRelAncIndex" 
              select="$thisAncIndex - $br1AncIndex"/>


This might seem a little bit complicated, however the idea is quite
simple.

Every node can be identified in a two-dimensional coordinate system, in
which the first axis is the "preceding" axis, and the second axis is
the "ancestor" axis (as we know, these two axes are non-overlapping).

That is, the pair:
 (count(preceding::node), count(ancestor::node))

uniquely identifies any node.

The above is an absolute coordinate system (relative to the root node).

We can express the pair of coordinates of a node relative to some
ancestor (in our case "branch1").

Then the corresponding node in the subtree rooted by "branch2" must
have the same pair of coordinates, relative to "branch2".

This simple relationship is expressed in the first XPath expression in
this message.

Cheers,
Dimitre Novatchev.



__________________________________________________
Do You Yahoo!?
Yahoo! Games - play chess, backgammon, pool and more
http://games.yahoo.com/

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


Current Thread