Re: node equality: fn:node-equal()

Kay, Michael wrote:

>>I'd like to compare two nodes for equality. I could do it by testing 
>>various aspects of the pair, thus writing my:node-equal(), but I'd 
>>prefer to have it available in the language.
>>
> You'll have to explain exactly what you mean by node equality.


Sorry for quoting myself, but I wrote
http://lists.w3.org/Archives/Public/public-qt-comments/2003May/0171.html
"It would test for  equality (not identity), and simply return true or 
false. I think that would be like fn:deep-equal(), but would not recurse 
down the tree; it would only test the single node, or the root note of 
the tree if the arg is a tree."

I think that's as much as I can provide.

http://www.w3.org/TR/xquery-operators/#func-deep-equal
######################################################################

"15.2.1.1 Deep Equality of Nodes

The following (recursive) tests are applied in order to determine 
whether two nodes are deep equal.

If the two nodes are of different node-kinds, the result is false.

if (fn:node-kind($parameter1) ne fn:node-kind($parameter2))
then false
else

If the two nodes have names, and the names are different when compared 
as expanded-QNames, the result is false.

if (fn:node-name($parameter1) != fn:node-name($parameter2))
then false
else

If the two nodes are text nodes, comment nodes, processing instruction 
nodes, or namespace nodes, then the result is true if and only if the 
two nodes have equal string-values, when compared using the selected 
collation.

if (some $n in ("text", "comment", "processing-instruction", "namespace")
          satisfies $n eq fn:node-kind($parameter1)
     and fn:compare
         (fn:string($parameter1), fn:string($parameter2), $collation) ne 0)
then false
else

If either node has attributes, and if either node has an attribute that 
is not deep-equal to an attribute of the other node, using the selected 
collation, then the result is false.

if (some $a1 in $parameter1/@* satisfies
       not (some $a2 in $parameter2/@*
            satisfies fn:deep-equal($a1, $a2, $collation))
     or some $a2 in $parameter2/@* satisfies
       not (some $a1 in $parameter1/@*
            satisfies fn:deep-equal($a1, $a2, $collation)))
then false
else

If neither node has element children, then the result is true only if 
the other node also has simple content, and if the simple content of the 
two nodes (that is, the result of the fn:data() function) is equal under 
the rules for the fn:deep-equal() function, using the selected 
collation. (Note: attributes always have simple content.)

if (empty($parameter1/*) and empty($parameter2/*))
then fn:deep-equal( fn:data($parameter1),
                              fn:data($parameter2),
                              $collation )
else

Otherwise, the result is true if and only if the children of node 
$parameter1 are pairwise deep-equal to the children of node $parameter2, 
ignoring comment and processing instruction nodes in both cases.

fn:deep-equal( $parameter1/(* | text()),
                         $parameter2/(* | text()),
                         $collation )
"
######################################################################

So the test for a pair of nodes (single nodes or trees) could be:

######################################################################

If the two nodes are of different node-kinds, the result is false.

if (fn:node-kind($parameter1) ne fn:node-kind($parameter2))
then false
else

If the two nodes have names, and the names are different when compared 
as expanded-QNames, the result is false.

if (fn:node-name($parameter1) != fn:node-name($parameter2))
then false
else

If the two nodes are text nodes, comment nodes, processing instruction 
nodes, or namespace nodes, then the result is true if and only if the 
two nodes have equal string-values, when compared using the selected 
collation.

if (some $n in ("text", "comment", "processing-instruction", "namespace")
          satisfies $n eq fn:node-kind($parameter1)
     and fn:compare
         (fn:string($parameter1), fn:string($parameter2), $collation) ne 0)
then false
else

If either node has attributes, and if either node has an attribute that 
is not deep-equal to an attribute of the other node, using the selected 
collation, then the result is false.

if (some $a1 in $parameter1/@* satisfies
       not (some $a2 in $parameter2/@*
            satisfies fn:deep-equal($a1, $a2, $collation))
     or some $a2 in $parameter2/@* satisfies
       not (some $a1 in $parameter1/@*
            satisfies fn:deep-equal($a1, $a2, $collation)))
then false
else

If any of the nodes has element children, they are not compared.

######################################################################

> There are a
> great many possible definitions.


fn:equal could be exactly like fn:deep-equal, but not recurse down the 
tree. Compare two nodes (or atomic values); if the two args are trees, 
compare their root nodes.

> We have provided "eq"


Does the eq operator do what I describe above? Then I can use it.
But I can't find it's definition (there are around ten related specs). 
It would be great if in http://www.w3.org/TR/xquery-operators/ , 
mentions of "the eq operator" would be hyperlinked to it's defionition, 
or to the defining resource link.

> and "fn:deep-equal()"
> to support two possible definitions; it's not clear that there are other
> definitions of node equality that are sufficiently widely accepted that they
> should be in the core library. You can always write your own comparison
> function.


http://lists.w3.org/Archives/Public/public-qt-comments/2003May/0171.html
"I could do it by testing  various aspects of the pair, thus writing 
my:node-equal(), but I'd prefer to have it available in the language."


>>BTW, op:node-equal() still tests for identity instead of equality.
>>
> Yes, this internal function is designed to support the "is" operator. It's
> not a well-chosen name, but the name will never be seen by users.


The name is incorrect, and is published in a W3C spec draft. I can't see 
why it should not be corrected.

Tobi

-- 
http://www.pinkjuice.com/

Received on Wednesday, 14 May 2003 04:00:02 UTC