Re: Document Object Model (DOM) Level 3 XPath Specification

Curt Arnold wrote:

>http://www.w3.org/TR/query-datamodel/#primvalue appears to describe
>an coercion functions that would augment the number(), string() and
>boolean()
>functions already in XPath 1.0.
>
>For example, if a document has an associated schema and a "time" attribute
>is associated with a type derived from xs:time but my application wants
>to have it returned as a string, I could write its XPath query as either:
>
>String timeStr = (String) evaluate("string(@time)");
>
>or
>
>String timeStr = (String) evaluate("xs:string(@time)");
>
>Since I have the ability to coerce an XPath expression to any arbitrary
>builtin schema type, replicating this capability by an additional datatype
>argument on the evaluateAs function seems unnecessary.
>
>Time time = (Time) evaluate("xs:time(" + query + ")");
>
I am still struggling with this stuff.  First, just because there is a 
schema type, does not mean that there will be exactly one corresponding 
binding type that we know of that corresponds to it.  Secondly, in the 
absence of coercion, it appears (section 3.4) that an object can be of 
multiple types simultaneously, which is not likely to be true of the 
binding language types we try to coerce it to.

>>The methods of these interfaces have changed a bit since I started, so I
>>would not be opposed to renameing them appropriately.  I agree that
>>ActiveNodeSet behaves like a fail-fast iterator.  But I would be afraid
>>of confusion if we called the one type an iterator of the other, when it
>>is not.  The ActiveNodeSet does not iterate across the StaticNodeSet,
>>but rather across an active result set.  A StaticNodeSet snapshots a
>>list of the nodes in the ActiveNodeSet.  While the names might make
>>sense in isolation, together they seem quite misleading.  I would be
>>more inclined to try something like NodeSetIterator and NodeSetSnapshot.
>>
>
>The fact that NodeSet is a snapshot is really orthogonal to the interface,
>it is really
>more a quality of the underlying object returned by a particular method.
>Likewise
>all the text about liveness of NodeList's in the Core spec is really a
>quality of the
>the object returned by , for example, Element.attributes(), than having
>anything
>to do with the NodeList interface.  If there were functions in Core that
>returned
>static lists, I would prefer to be able to manipulate them using a generic
>interface
>that I could also use for dynamic node lists.
>
We could debate for some time whether these types of qualities should be 
part of the type of the interface.  My thinking is that they should be. 
 I want to know if / how these sets will not be shifting underneath me 
as I try to manipulate them.

>Between the XPath draft and Core, there are three interfaces to manipulate
>sets of Nodes, StaticNodeSet/NodeSet[Snapshot], NodeList and NamedNodeMap.
>All three interfaces have a length() and item() method, but there is no
>common
>interface supported by all and there should be.
>
I disagree that this conclusion should be automatic.  Having 
similar-looking methods does not necessarily mean that the objects are 
similar enough that one should be abstractly considered an instance of 
the other.  A NodeList is a very live object that has not been desired 
for XPath.  Many clients of XPath cannot tolerate XPath result sets that 
might skew as they are using them or might not match the hierarchy.  It 
is a shame that we have multiple interfaces, but trying to make them a 
single interface would only seem to make things appear simpler.  If 
there were use cases showing a common case that there is an important 
shared abstraction, then such might be considered.  I can tell you that 
for NodeList and NamedNodeMap a common interface was carefully considered.

>If being able to determine whether an NodeSet is static or dynamic is
>significant,
>then NodeSet could have an isDynamic() property and possibly a
>createStaticSet()
>method:
>
>public interface NodeSet {
>     public int getLength();
>     public Node getItem(int index);
>     public boolean getIsDynamic();
>     public boolean getIsOrdered();
>     public NodeSet createStaticSet();
>}
>
>Element.getAttributes() could return an object that, in addition to
>supporting NamedNodeMap,
>would support NodeSet with isDynamic = true and isOrdered = false.  If you
>wanted to take
>a snapshot of the attribute list, then you could call createStaticSet().
>(The members of the set would be fixed, however the properties of individual
>members could still change)
>
>Element.getChildren() could return an object that, in addition to supporting
>NodeList,
>would support NodeSet with isDynamic = true and isOrdered = true.
>
While this is one way of specifying it, I do not think it is as useful, 
because it does not permit me to specify in my function which type I can 
deal with -- either a node set that gets out of sync with the hierarchy, 
or a node set that fails hard if the hierarchy mutates.  I think you 
would have to write multiple versions of a method with quite different 
behaviors depending upon which interface you are dealing with, and 
NodeList is a third, quite different, behavior.  Just because such 
behaviors do not affect the signature of the interfaces does not mean 
that the type should not guarantee them for you.  In this case, the 
behaviors of a NodeList and StaticNodeSet, and ActiveNodeSet have been 
clearly defined in the specification.

Ray Whitmer
rayw@netscape.com

Received on Sunday, 1 July 2001 10:16:58 UTC