[xquery-talk] distance between elements and hierarchical order

Sergio Andreozzi sergio.andreozzi at cnaf.infn.it
Fri Dec 9 13:25:50 PST 2005


I worked also on the following issue:

3. measure the distance between two elements as regards the document 
structure

the solution that I've defined so far works in the following way: given 
two elements, for each of them I build a sequences with their QName plus 
the QNames of their ancestors; I compare the two sequences memberwise 
and I count the common QNames starting from the root; finally, I add the 
number of QNames in the first sequence to the number of QNames in the 
second sequence, I substract twice the common elements and I add 1 for 
the closest common ancestor:

let $x-names := 
(doc("test.xml")/S/A/B/F)[2]/ancestor-or-self::element()/name(),
     $y-names := 
(doc("test.xml")/S/A/B/C/G/H)[3]/ancestor-or-self::element()/name()

return count($x-names) + count($y-names) + 1 - 2*count(
   		for $x-name at $x-pos in $x-names
   	 	where $x-name eq $y-names[$x-pos]
              	return 1)     	
		
as regards the example in 
http://xquery.com/pipermail/talk/2005-December/000944.html, this measure 
always provides 5.

This is the best refinement I managed to design so far in order to 
perform this measure.

Regards, Sergio


Sergio Andreozzi wrote:
> David Carlisle wrote:
> 
>> In the original problem I don't think you need to explictly iterate over
>> the ancestor lists then use count and min, you just walk up the
>> ancestors of x which are not ancestors of y , then up one level to the
>> nearest common ancestor then down the ancestors of y that are not
>> ancestors of x so the distance is
>>
>> count($x-ancestors)+count($y-ancestors)+1-2*count($x-ancestors 
>> intersect $y-ancestors)
>>
>> where x-ancestors is as in the posted code the ancestor-or-self:: axis
>> from $x
> 
> 
> 
> the final solution for prob. no.2 should be this one then:
> 
> let $x := ...
>     $y := ...
> 
> let $x-ancestors := $x/ancestor-or-self::element(),
>     $y-ancestors := $y/ancestor-or-self::element()
> 
> return count($x-ancestors)+count($y-ancestors)+1-2*count($x-ancestors 
> intersect $y-ancestors)
> 
> ex.1
> 
> let $x := (doc("test.xml")/S/A/B/F)[1],
>     $y := (doc("test.xml")/S/A/B/C/G/H)[3]
> 
> result is 7
> 
> ex.2
> 
> let $x := (doc("test.xml")/S/A/B/F)[2],
>     $y := (doc("test.xml")/S/A/B/C/G/H)[3]
> 
> result is 5
> 
> where test.xml is:
> 
> <S>
>     <A>
>         <B>
>             <F>4</F>
>             <C>
>                 <D>3</D>
>                 <E>5</E>
>                 <G>
>                     <H>3</H>
>                 </G>
>                 <G>
>                     <H>2</H>
>                 </G>
>             </C>
>         </B>
>         <B>
>         <F>2</F>
>         <C>
>             <G>
>                  <H>2</H>
>             </G>
>         </C>
>         </B>
>     </A>
> </S>
> 
> 
> 
> thank you very much for your help.
> 
>     Kind regards, Sergio
> _______________________________________________
> talk at xquery.com
> http://xquery.com/mailman/listinfo/talk


-- 
Sergio Andreozzi
INFN-CNAF,                        Tel: +39 051 609 2860
Viale Berti Pichat, 6/2           Fax: +39 051 609 2746
40126 Bologna (Italy)             Web: http://www.cnaf.infn.it/~sergio


More information about the talk mailing list