- From: Michael Dyck <MichaelDyck@home.com>
- Date: Sat, 16 Sep 2000 16:03:42 -0700
- To: www-xml-linking-comments@w3.org
Christopher R. Maden <crism@lexica.net> wrote:
>
> XPointer modifies the XPath grammar to have
>
> NodeType ::= 'comment'
> | 'text'
> | 'processing-instruction'
> | 'node'
> | 'point'
> | 'range'
>
> However, it does not change the NodeTest definition:
>
> [7] NodeTest ::= NameTest
> | NodeType '(' ')'
> | 'processing-instruction' '(' Literal ')'
>
> So as far as I can tell, point() is legal, but there's really no way of
> saying *which* point you want to refer to.
There isn't supposed to be. It merely tests whether the context location
is a point location (any point location). This is the same as in XPath,
where "comment()" tests whether the context node is a comment node,
"text()" tests whether it's a text node, etc.
However, you raise an interesting issue: how *do* you refer to a
particular point location? Specifically, given point location P defined by
container node C and index I, how do you construct an XPointer that yields
P? It sounds like a simple matter, and one that could easily arise in
applications, but I don't think there's a complete solution. Here are the
bits that I came up with.
Let c denote an Expr that yields C, and i an Expr that evaluates to I.
Construct p, an Expr that yields P.
If P is a character-point:
p1 = start-point(string-range(c,"",i+1,0))
where the "0" is actually arbitrary.
If P is a node-point, this almost works:
p2 = start-point(range(c/node()[i+1]))
but fails when P is the "last" point within C (I = #children of C).
For that, you could use:
p2 = end-point(range(c/node()[i]))
which fails when P is the "first" point within C (I = 0).
Combining those (fairly redundantly):
p2 = (start-point(range(c/node()[i+1])) |
end-point(range(c/node()[i ])) )
But can we combine those two cases (character-point and node-point)
into a single expression? We can't just take the union:
p = p1 | p2
because when P is a node-point, p1 can yield a character-point != P.
[Conversely, when P is a character-point, p2 will not yield anything,
because the container node of a character-point cannot have children.]
So we need an expression like:
p = p1[if c isn't an element node or a root node] | p2
But I don't think there's a predicate that fails exactly when a
location is an element or root node. This:
[not(self::* or .=/)]
is close, except that "=" actually operates on string-values, so
the predicate fails in a few cases where it shouldn't.
So that's as far as I got. The problem would be a lot easier to solve if
we were to define a new axis "points" which contains all the point
locations within the context node (i.e., all the point locations whose
container node is the context node). Then
p = c/points[i+1]
would be the general solution. But it may be too late to add something
that significant to the XPointer spec.
-Michael Dyck
Received on Saturday, 16 September 2000 19:08:51 UTC