W3C home > Mailing lists > Public > www-xpath-comments@w3.org > January to March 2001

Re: Axes

From: Michael Dyck <MichaelDyck@home.com>
Date: Wed, 17 Jan 2001 23:28:47 -0800
Message-ID: <3A669B2F.71E8512D@home.com>
To: Adam Van Den Hoven <Adam.Hoven@bluezone.net>
CC: "'www-xpath-comments@w3.org'" <www-xpath-comments@w3.org>
Adam Van Den Hoven wrote:
> 
> While there are preceding-sibling and following-sibling axes, there is no
> sibling axis (or a sibling-or-self axis but that may be too much).

sibling-or-self::x would just be parent::*/child::x, I think, so not that
useful.

> It would seem that the predicate
>     [sibling::node()/@role != self::node/@role]
> would be easier to process than
>     [preceding-sibling::node()/@role != self::node/@role and
>      following-sibling::node()/@role != self::node/@role]
> simply by viture of the fact that the first retrieves one node set and
> the other does it twice.

Actually, the two predicates wouldn't be equivalent. The first would be true
iff any sibling's role differed from the context node's role.  The second is
true iff both a preceding sibling's role and a following sibling's role
differ from the context node's role.

I suspect what you had in mind was a predicate that would be true iff
*every* sibling's role differs from the context node's role, in which case
you should be comparing
    [not(sibling::node()/@role = self::node()/@role)]
with
    [not(preceding-sibling::node()/@role = self::node()/@role) and
     not(following-sibling::node()/@role = self::node()/@role)]
or with
    [not(preceding-sibling::node()/@role = self::node()/@role or
         following-sibling::node()/@role = self::node()/@role)]
or with
    [not((preceding-sibling::node()|following-sibling::node())/@role =
         self::node()/@role)]

That is,
    sibling::x
is semantically equivalent to
    (preceding-sibling::x|following-sibling::x)
and syntactically equivalent in some contexts.

> There is also the case where you want to tell someone (like you see at
> Amazon) "the majority of people who bought this thing also bought ...". A
> part of the path that would be able to tell you these things might be:
> 
> /Invoices/Invoice/Item[@partNo='sku2']/sibling::Item

This is a case where the syntactic substitution isn't valid (grrr), but I
think
    /Invoices/Invoice[Item[@partNo='sku2']]/Item[@partNo!='sku2']
would do what you want. (It's not exactly equivalent, but the difference
only arises when sibling Items have the same partNo, which I imagine is not
the case.) Of the two, I prefer yours, but if
/Invoices/Invoice/Item[@partNo='sku2']/(preceding-sibling::Item|following-sibling::Item)
were valid, it would be harder to justify introducing a new axis.

> (I'm not sure you can mix the abbreviated syntax
> with the full syntax but I'm going to do it for brevity).

Sure you can.

> So if I wanted to know all the companies
> that published my books I could use
>     /library/book/publisher[../author = 'Adam van den Hoven']
> or
>     /library/book/publisher[
>         preceding-sibling::author = 'Adam van den Hoven' or
>         following-sibling::author = 'Adam van den Hoven'].
> It may be faster (and IMHO more obvious) to use
>     /library/book/publisher[sibling::author = 'Adam van den Hoven'].
> That is something an implementer would know better than I.

My guess is that it would be about as fast as your first choice.
You could also say
      /library/book[author = 'Adam van den Hoven']/publisher
which arguably might be faster than any of them.
As for obviousness, that's in the eye of the beholder.

-Michael Dyck
Received on Thursday, 18 January 2001 02:30:40 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 5 February 2014 07:15:20 UTC