Order of nodes in reversed axes

Wednesday, 16 April 2014 · 10 messages · last reply 17 Apr 2014
DR
David Rudelin reply to José Tomás Atria, 16 Apr 2014, 22:0016 Apr 2014 20:45 #
Mr. Atria, You left out a key element from the answer you got from stack overflow. Note that Dimitre's response used a filter expression (path expression) [predicate] not a simple path expression The ()s are critical.
$test//child/ancestor-or-self::test[ last() ]
is very different from ($test//child/ancestor-or-self::test)[ last() ] The ancestor axis is a reverse axis, but when the xpath expression is complete, the sequence of nodes are then put in document order regardless of what order the last axis had. In any event, I don't understand what is wrong with simply $test/ancestor::element()[1] Perhaps I don't understand your question (which is simpler than the Stack Overflow question you linked to). But if you are just looking for the nearest ancestor element, then it seems that $test/ancestor::element()[1] should give it to you.
DR
David Rudel16 Apr 2014 20:47 #
More specifically, I don't understand what the difference is between "nearest ancestor element" and "parent."
Quoted text · David Rudel · 28 lines
On Wed, Apr 16, 2014 at 8:45 PM, David Rudel <fwqhgads at gmail.com> wrote: > Mr. Atria, > You left out a key element from the answer you got from stack overflow. > > Note that Dimitre's response used a filter expression > (path expression) [predicate] > > not a simple path expression > > The ()s are critical. > > $test//child/ancestor-or-self::test[ last() ] > > is very different from > > ($test//child/ancestor-or-self::test)[ last() ] > > The ancestor axis is a reverse axis, but when the xpath expression is > complete, the sequence of nodes are then put in document order > regardless of what order the last axis had. > > In any event, I don't understand what is wrong with simply > $test/ancestor::element()[1] > > Perhaps I don't understand your question (which is simpler than the > Stack Overflow question you linked to). But if you are just looking > for the nearest ancestor element, then it seems that > $test/ancestor::element()[1] should give it to you.
-- "A false conclusion, once arrived at and widely accepted is not dislodged easily, and the less it is understood, the more tenaciously it is held." - Cantor's Law of Preservation of Ignorance.
DR
David Rudelin reply to José Tomás Atria, 16 Apr 2014, 22:4816 Apr 2014 21:16 #
I apologize if I'm being dense, but I don't understand how the nearest ancestor can be anything other than the parent. Could you please give an example? I just want to make sure I haven't sent you off with the wrong expression for your intended usage.
Quoted text · José Tomás Atria · 48 lines
On Wed, Apr 16, 2014 at 8:48 PM, José Tomás Atria <jtatria at gmail.com> wrote: > Thank you all for your answers. > > I was just tryig to determine if $test/ancestor::element()[1] would be the > correct way of getting the nearest ancestor, as I couldn't find whether axes > were ordered or not in the xpath specification. > > Thanks! > > ps: Parent doesn't apply, because the relevant node is not always the > parent, but the first node with a given name. > > > On Wed, Apr 16, 2014 at 2:45 PM, David Rudel <fwqhgads at gmail.com> wrote: >> >> Mr. Atria, >> You left out a key element from the answer you got from stack overflow. >> >> Note that Dimitre's response used a filter expression >> (path expression) [predicate] >> >> not a simple path expression >> >> The ()s are critical. >> >> $test//child/ancestor-or-self::test[ last() ] >> >> is very different from >> >> ($test//child/ancestor-or-self::test)[ last() ] >> >> The ancestor axis is a reverse axis, but when the xpath expression is >> complete, the sequence of nodes are then put in document order >> regardless of what order the last axis had. >> >> In any event, I don't understand what is wrong with simply >> $test/ancestor::element()[1] >> >> Perhaps I don't understand your question (which is simpler than the >> Stack Overflow question you linked to). But if you are just looking >> for the nearest ancestor element, then it seems that >> $test/ancestor::element()[1] should give it to you. > > > > > -- > entia non sunt multiplicanda praeter necessitatem
-- "A false conclusion, once arrived at and widely accepted is not dislodged easily, and the less it is understood, the more tenaciously it is held." - Cantor's Law of Preservation of Ignorance.
DR
David Rudelin reply to José Tomás Atria, 16 Apr 2014, 23:2316 Apr 2014 21:36 #
Ah, okay. I didn't catch that you wanted "the nearest ancestor with a particular name." In that case then I think you are golden. If there is a chance that the element itself is a div1 element, then you will want to use ancestor-or-self instead, but otherwise I think you have it right.
Quoted text · José Tomás Atria · 117 lines
On Wed, Apr 16, 2014 at 9:22 PM, José Tomás Atria <jtatria at gmail.com> wrote: > That should have been ancestor::div1[1]. pardon the typo. > > > On Wed, Apr 16, 2014 at 3:21 PM, José Tomás Atria <jtatria at gmail.com> wrote: >> >> let $test := >> element div0{ >> attribute id { 4 }, >> element div1 { >> attribute id { 3 }, >> element div1 { >> attribute id { 2 }, >> element para { >> attribute id { 1 }, >> element child { } >> } >> } >> } >> } >> >> I want to get the "smallest" div1 for a given child. this is, the <div1 >> id=2> element. >> >> As far as I've understood the answers given here, reverse axes are ordered >> from the context node, so the expression >> >> $test//child/ancestor-or-self::div1[1] will get me what i want, while >> $test//child/parent() will give me <para id=1> >> >> Needless to say, my data is not particularly well behaved :) >> >> Thanks! >> >> >> On Wed, Apr 16, 2014 at 3:16 PM, David Rudel <fwqhgads at gmail.com> wrote: >>> >>> I apologize if I'm being dense, but I don't understand how the nearest >>> ancestor can be anything other than the parent. Could you please give >>> an example? >>> >>> I just want to make sure I haven't sent you off with the wrong >>> expression for your intended usage. >>> >>> On Wed, Apr 16, 2014 at 8:48 PM, José Tomás Atria <jtatria at gmail.com> >>> wrote: >>> > Thank you all for your answers. >>> > >>> > I was just tryig to determine if $test/ancestor::element()[1] would be >>> > the >>> > correct way of getting the nearest ancestor, as I couldn't find whether >>> > axes >>> > were ordered or not in the xpath specification. >>> > >>> > Thanks! >>> > >>> > ps: Parent doesn't apply, because the relevant node is not always the >>> > parent, but the first node with a given name. >>> > >>> > >>> > On Wed, Apr 16, 2014 at 2:45 PM, David Rudel <fwqhgads at gmail.com> >>> > wrote: >>> >> >>> >> Mr. Atria, >>> >> You left out a key element from the answer you got from stack >>> >> overflow. >>> >> >>> >> Note that Dimitre's response used a filter expression >>> >> (path expression) [predicate] >>> >> >>> >> not a simple path expression >>> >> >>> >> The ()s are critical. >>> >> >>> >> $test//child/ancestor-or-self::test[ last() ] >>> >> >>> >> is very different from >>> >> >>> >> ($test//child/ancestor-or-self::test)[ last() ] >>> >> >>> >> The ancestor axis is a reverse axis, but when the xpath expression is >>> >> complete, the sequence of nodes are then put in document order >>> >> regardless of what order the last axis had. >>> >> >>> >> In any event, I don't understand what is wrong with simply >>> >> $test/ancestor::element()[1] >>> >> >>> >> Perhaps I don't understand your question (which is simpler than the >>> >> Stack Overflow question you linked to). But if you are just looking >>> >> for the nearest ancestor element, then it seems that >>> >> $test/ancestor::element()[1] should give it to you. >>> > >>> > >>> > >>> > >>> > -- >>> > entia non sunt multiplicanda praeter necessitatem >>> >>> >>> >>> -- >>> >>> "A false conclusion, once arrived at and widely accepted is not >>> dislodged easily, and the less it is understood, the more tenaciously >>> it is held." - Cantor's Law of Preservation of Ignorance. >> >> >> >> >> -- >> entia non sunt multiplicanda praeter necessitatem > > > > > -- > entia non sunt multiplicanda praeter necessitatem
-- "A false conclusion, once arrived at and widely accepted is not dislodged easily, and the less it is understood, the more tenaciously it is held." - Cantor's Law of Preservation of Ignorance.
JA
José Tomás Atria16 Apr 2014 22:00 #
Hello all, I've been looking for an authoritative answer to this, but have been unable to find one. I'm trying to reliably get the nearest ancestor of a node. ie with this test data:
let $test :=
element test {
  attribute id { 4 },
  element test {
    attribute id { 3 },
    element test {
      attribute id { 2 },
      element test {
        attribute id { 1 },
        element child { }
      }
    }
  }
}
i want an expression that will return node test/@id=1 from child. Stackoverflow says that this:
$test//child/ancestor-or-self::test[ last() ]
Should work (here<http://stackoverflow.com/questions/6554488/how-to-get-the-nearest-ancestor-or-child-of-an-ancestor-with-xpath>), but since I couldn't find any indication to reversed axes being ordered in the w3c spec for reverse axes in xpath 2.0 (here<http://www.w3.org/TR/xpath20/#doc-xpath-ReverseAxis>), I suspected that this would be implementation dependent, and sure enough, in BaseX, that expression returns
<test id="4">
  <test id="3">
    <test id="2">
      <test id="1">
        <child/>
      </test>
    </test>
  </test>
</test>
while this
$test//child/ancestor-or-self::test[ 1 ]
​correctly returns
<test id="1">
  <child/>
</test>​
Is there an authoritative way of getting the nearest ancestor of a given node? Note that in my actual use case, names are the same, and desired ids are unknown. Thanks! jta
-- entia non sunt multiplicanda praeter necessitatem
JA
José Tomás Atriain reply to David Rudel, 16 Apr 2014, 20:4516 Apr 2014 22:48 #
Thank you all for your answers. I was just tryig to determine if $test/ancestor::element()[1] would be the correct way of getting the nearest ancestor, as I couldn't find whether axes were ordered or not in the xpath specification. Thanks! ps: Parent doesn't apply, because the relevant node is not always the parent, but the first node with a given name.
Quoted text · David Rudel · 29 lines
On Wed, Apr 16, 2014 at 2:45 PM, David Rudel <fwqhgads at gmail.com> wrote: > Mr. Atria, > You left out a key element from the answer you got from stack overflow. > > Note that Dimitre's response used a filter expression > (path expression) [predicate] > > not a simple path expression > > The ()s are critical. > > $test//child/ancestor-or-self::test[ last() ] > > is very different from > > ($test//child/ancestor-or-self::test)[ last() ] > > The ancestor axis is a reverse axis, but when the xpath expression is > complete, the sequence of nodes are then put in document order > regardless of what order the last axis had. > > In any event, I don't understand what is wrong with simply > $test/ancestor::element()[1] > > Perhaps I don't understand your question (which is simpler than the > Stack Overflow question you linked to). But if you are just looking > for the nearest ancestor element, then it seems that > $test/ancestor::element()[1] should give it to you. >
-- entia non sunt multiplicanda praeter necessitatem
JA
José Tomás Atriain reply to David Rudel, 16 Apr 2014, 21:1616 Apr 2014 23:22 #
let $test :=
element div0{
  attribute id { 4 },
  element div1 {
    attribute id { 3 },
    element div1 {
      attribute id { 2 },
      element para {
        attribute id { 1 },
        element child { }
      }
    }
  }
}
I want to get the "smallest" div1 for a given child. this is, the <div1 id=2> element. As far as I've understood the answers given here, reverse axes are ordered from the context node, so the expression
$test//child/ancestor-or-self::div1[1] will get me what i want, while
$test//child/parent() will give me <para id=1>
Needless to say, my data is not particularly well behaved :) Thanks!
Quoted text · David Rudel · 68 lines
On Wed, Apr 16, 2014 at 3:16 PM, David Rudel <fwqhgads at gmail.com> wrote: > I apologize if I'm being dense, but I don't understand how the nearest > ancestor can be anything other than the parent. Could you please give > an example? > > I just want to make sure I haven't sent you off with the wrong > expression for your intended usage. > > On Wed, Apr 16, 2014 at 8:48 PM, José Tomás Atria <jtatria at gmail.com> > wrote: > > Thank you all for your answers. > > > > I was just tryig to determine if $test/ancestor::element()[1] would be > the > > correct way of getting the nearest ancestor, as I couldn't find whether > axes > > were ordered or not in the xpath specification. > > > > Thanks! > > > > ps: Parent doesn't apply, because the relevant node is not always the > > parent, but the first node with a given name. > > > > > > On Wed, Apr 16, 2014 at 2:45 PM, David Rudel <fwqhgads at gmail.com> wrote: > >> > >> Mr. Atria, > >> You left out a key element from the answer you got from stack overflow. > >> > >> Note that Dimitre's response used a filter expression > >> (path expression) [predicate] > >> > >> not a simple path expression > >> > >> The ()s are critical. > >> > >> $test//child/ancestor-or-self::test[ last() ] > >> > >> is very different from > >> > >> ($test//child/ancestor-or-self::test)[ last() ] > >> > >> The ancestor axis is a reverse axis, but when the xpath expression is > >> complete, the sequence of nodes are then put in document order > >> regardless of what order the last axis had. > >> > >> In any event, I don't understand what is wrong with simply > >> $test/ancestor::element()[1] > >> > >> Perhaps I don't understand your question (which is simpler than the > >> Stack Overflow question you linked to). But if you are just looking > >> for the nearest ancestor element, then it seems that > >> $test/ancestor::element()[1] should give it to you. > > > > > > > > > > -- > > entia non sunt multiplicanda praeter necessitatem > > > > -- > > "A false conclusion, once arrived at and widely accepted is not > dislodged easily, and the less it is understood, the more tenaciously > it is held." - Cantor's Law of Preservation of Ignorance. >
-- entia non sunt multiplicanda praeter necessitatem
JA
José Tomás Atria16 Apr 2014 23:23 #
That should have been ancestor::div1[1]. pardon the typo.
Quoted text · José Tomás Atria · 106 lines
On Wed, Apr 16, 2014 at 3:21 PM, José Tomás Atria <jtatria at gmail.com> wrote: > let $test := > element div0{ > attribute id { 4 }, > element div1 { > attribute id { 3 }, > element div1 { > attribute id { 2 }, > element para { > attribute id { 1 }, > element child { } > } > } > } > } > > I want to get the "smallest" div1 for a given child. this is, the <div1 > id=2> element. > > As far as I've understood the answers given here, reverse axes are ordered > from the context node, so the expression > > $test//child/ancestor-or-self::div1[1] will get me what i want, while > $test//child/parent() will give me <para id=1> > > Needless to say, my data is not particularly well behaved :) > > Thanks! > > > On Wed, Apr 16, 2014 at 3:16 PM, David Rudel <fwqhgads at gmail.com> wrote: > >> I apologize if I'm being dense, but I don't understand how the nearest >> ancestor can be anything other than the parent. Could you please give >> an example? >> >> I just want to make sure I haven't sent you off with the wrong >> expression for your intended usage. >> >> On Wed, Apr 16, 2014 at 8:48 PM, José Tomás Atria <jtatria at gmail.com> >> wrote: >> > Thank you all for your answers. >> > >> > I was just tryig to determine if $test/ancestor::element()[1] would be >> the >> > correct way of getting the nearest ancestor, as I couldn't find whether >> axes >> > were ordered or not in the xpath specification. >> > >> > Thanks! >> > >> > ps: Parent doesn't apply, because the relevant node is not always the >> > parent, but the first node with a given name. >> > >> > >> > On Wed, Apr 16, 2014 at 2:45 PM, David Rudel <fwqhgads at gmail.com> >> wrote: >> >> >> >> Mr. Atria, >> >> You left out a key element from the answer you got from stack overflow. >> >> >> >> Note that Dimitre's response used a filter expression >> >> (path expression) [predicate] >> >> >> >> not a simple path expression >> >> >> >> The ()s are critical. >> >> >> >> $test//child/ancestor-or-self::test[ last() ] >> >> >> >> is very different from >> >> >> >> ($test//child/ancestor-or-self::test)[ last() ] >> >> >> >> The ancestor axis is a reverse axis, but when the xpath expression is >> >> complete, the sequence of nodes are then put in document order >> >> regardless of what order the last axis had. >> >> >> >> In any event, I don't understand what is wrong with simply >> >> $test/ancestor::element()[1] >> >> >> >> Perhaps I don't understand your question (which is simpler than the >> >> Stack Overflow question you linked to). But if you are just looking >> >> for the nearest ancestor element, then it seems that >> >> $test/ancestor::element()[1] should give it to you. >> > >> > >> > >> > >> > -- >> > entia non sunt multiplicanda praeter necessitatem >> >> >> >> -- >> >> "A false conclusion, once arrived at and widely accepted is not >> dislodged easily, and the less it is understood, the more tenaciously >> it is held." - Cantor's Law of Preservation of Ignorance. >> > > > > -- > entia non sunt multiplicanda praeter necessitatem >
-- entia non sunt multiplicanda praeter necessitatem
JA
José Tomás Atriain reply to David Rudel, 16 Apr 2014, 21:3617 Apr 2014 00:00 #
Just for the sake of completion, the authoritative answer is here<http://www.w3.org/TR/xpath/#predicates> : "The proximity position of a member of a node-set with respect to an axis is defined to be the position of the node in the node-set ordered in document order if the axis is a forward axis and *ordered in reverse document order if the axis is a reverse axis*. The first position is 1."
Quoted text · David Rudel · 6 lines
Ah, okay. I didn't catch that you wanted "the nearest ancestor with a > particular name." In that case then I think you are golden. If there > is a chance that the element itself is a div1 element, then you will > want to use ancestor-or-self instead, but otherwise I think you have > it right. >
​ Hopefully, I will never have to find the nearest div for a div in this collection, the objective was to locate the smallest container for an infringing non-container (ie, not a div) element. So I think I'm done here. Thanks! ​
-- entia non sunt multiplicanda praeter necessitatem
LQ
Liam R E Quin17 Apr 2014 04:48 #
Quoted text · José Tomás Atria · 3 lines
On Wed, 2014-04-16 at 15:59 -0400, José Tomás Atria wrote: > Just for the sake of completion, the authoritative answer is > here<http://www.w3.org/TR/xpath/#predicates>
Erm, http://www.w3.org/TR/xpath-30/#id-predicate is closer - XPath 1.0 is rather old and is not really the basis for XQuery. XQuery 1.0 - http://www.w3.org/TR/xquery/#id-predicates XQuery 3.0 (just released) - http://www.w3.org/TR/xquery-30/#id-predicate Hope this helps. Liam
-- Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/ Pictures from old books: http://fromoldbooks.org/ Ankh: irc.sorcery.net irc.gnome.org freenode/#xml

⚡Generated with XQuery