Re: XPointer question - selecting locations from a location-set

Daniel Veillard (Daniel.Veillard@w3.org) wrote:
>
> Jiri Jirat wrote:
> >
> > If I want to select the point (marked X) just before the string-range
> > 'another', which expression is correct?
> >
> > Is this correct?:
> > xpointer(string-range(//*,'another')[0])
> 
>   Hum, no, that would select the first range in the returned location set

Actually, the first one would be selected using the predicate [1]. Using
the predicate [0] guarantees that the expression will never select
anything, and thus that the XPointer will always have a sub-resource
error.

> > Or should it look like this?:
> > xpointer(string-range(//*,'another')[1][0])
> 
>   I think this would return an empty set,

That is, it wouldn't select anything, and this XPointer also has a
sub-resource error.

> > Or should there be some parentheses?
> 
>   IMHO the right thing is to use the 4th parameter of string-range to
> limit the range to the point starting it:
> 
> xpointer(string-range(//*,'another',1,0))

This selects the (collapsed) string-range that begins and ends immediately
before the 'a' of 'another', which is not quite what was requested.
Instead,

    xpointer(start-point(string-range(//*,'another',1,0)))

will select the *point* immediately before the 'a' of 'another'. Note that
for the 4th argument to 'string-range', you could use a number other than
'0', or just omit it, since you're only extracting the start-point and
don't care where the end-point of the range falls. Also, '1' is the
default for the 3rd argument, so you could simplify the expression to

    xpointer(start-point(string-range(//*,'another')))

> > IMPORTANT: here, in this example, the location-set returned by
> > "string-range(//*,'another')" consists just of ONE location.

Actually, this raises an interesting point. The path-expression //*
selects all element nodes in the document tree, and in fact *two* of them
have "another" in their string-value: the second <BBB> element obviously,
but also the <AAA> element, whose string value is the concatenation of the
string-values of all text nodes in the document. So the string-range()
call finds two locations in //* that have a match for "another". But does
it return two range locations, or just one?  I'm pretty sure the answer is
one, but it's not immediately obvious from the XPointer spec.

> > ===============================
> > Here is XML file:
> > ===============================
> >  <AAA>
> >    <BBB bbb="111">
> >      Text in the first element BBB.
> >    </BBB>
> >    <BBB bbb="222">
> >       Text in Xanother element BBB.
> >      <DDD ddd="999">
> >        Text in more nested element.
> >      </DDD>
> >    </BBB>
> >    <CCC ccc="123" xxx="321">
> >      Again some text in some element.
> >    </CCC>
> >  </AAA>
> > ===============================

> > May be, my question is not very clear, please, look at
> > http://www.zvon.org/xxl/xpointer/tutorial/OutputExamples/xml40_out.xml.html
> > and tell me your opinion.

I think you have misunderstood the definition of "point location":
    A location of type point is defined by a node, called the
    "container node", and a non-negative integer, called the "index".
You seem to infer that this allows you to write
    c[i]
to identify the point whose container node is yielded by 'c' and whose
index is yielded by 'i'. It doesn't. Instead, that expression selects the
i'th item of the ordered set selected by 'c'.  In general, constructing an
expression that *does* identify the given point is quite tricky. See
http://lists.w3.org/Archives/Public/www-xml-linking-comments/2000JulSep/0163.html
for my not-quite-complete attempt at it.

-Michael Dyck

Received on Wednesday, 22 November 2000 04:26:11 UTC