$node//text()[1], why doesn't it return the 1st text node?

Wednesday, 2 March 2016 · 6 messages · last reply 8 Mar 2016
JE
Jens Eratin reply to France Baril, 2 Mar 2016, 21:172 Mar 2016 20:28 #

This is a matter of precedence.

Quoted text · France Baril · 1 line
> <li>{ $node//text()[1] }</li>

Has the meaning of "return all text nodes, that are in first position of their encapsulating element". Consider the intermediate result after partial evaluation to be something like

("allo!"[1], "Il pleut des clous."[1])

Applying parenthesis as you proposed in #4 resolves the issue:

Quoted text · France Baril · 1 line
> <li>{ ($node//text())[1] }</li>

resulting in

("allo!", "Il pleut des clous.")[1]

instead.

This is not an issue in $5, as all text nodes are stored in a sequence (which is flattened), and you return the first result of the flattened sequence.

-- Jens Erat Universität Konstanz Kommunikations-, Infomations-, Medienzentrum (KIM) Abteilung Basisdienste D-78457 Konstanz Mail: jens.erat at uni-konstanz.de
FB
France Baril2 Mar 2016 21:17 #

Hi,

I was having issues manipulating text nodes. I found a way around my issue, but I'm still thinking that my 1st syntax to get the first text node of a sequence should have worked.

My question is given all the example below, is #2 returning the expected value? I was expecting it would work like the syntax for elements in #3 and return the same result as #4 and #5

let $node := <p><b>allo!</b> Il pleut des clous.</p>
let $node2 := <ul><li>1</li><li>2</li></ul>
let $text-node := $node//text()
return
  <ul>
    <li>{$text-node}</li>
    <li>{$node//text()[1]}</li>
    <li>{$node2//li[1]}</li>
    <li>{($node//text())[1]}</li>
    <li>{$text-node[1]}</li>
    <li>{$node//text()[1][1]}</li>
    <li>{for $i in $node//text() return <span>{$i}</span>}</li>
    <li>{for $i in $text-node return <span>{$i}</span>}</li>
 </ul>

<ul>
  <li>allo! Il pleut des clous.</li>
  <li>allo! Il pleut des clous.</li>
  <li>
    <li>1</li>
  </li>
  <li>allo!</li>
  <li>allo!</li>
  <li>allo! Il pleut des clous.</li>
  <li>
    <span>allo!</span>
    <span> Il pleut des clous.</span>
  </li>
  <li>
    <span>allo!</span>
    <span> Il pleut des clous.</span>
  </li>
</ul>
-- France Baril Architecte documentaire / Documentation architect france.baril at architextus.com
CG
Christian Grünin reply to Jens Erat, 2 Mar 2016, 20:282 Mar 2016 21:43 #

And a little addition:

  $node//text()[1]

…is an abbreviation for…

  $node/descendant-or-self::node()/child::text()[1]

However, you are probably looking for:

  $node/descendant::text()[1]

It’s completely fine to use parentheseses, as in this case, your query will exactly be rewritten as shown above.

Quoted text · Jens Erat · 33 lines
On Wed, Mar 2, 2016 at 8:28 PM, Jens Erat <jens.erat at uni-konstanz.de> wrote: > This is a matter of precedence. > >> <li>{ $node//text()[1] }</li> > > Has the meaning of "return all text nodes, that are in first position of > their encapsulating element". Consider the intermediate result after > partial evaluation to be something like > > ("allo!"[1], "Il pleut des clous."[1]) > > Applying parenthesis as you proposed in #4 resolves the issue: > >> <li>{ ($node//text())[1] }</li> > > resulting in > > ("allo!", "Il pleut des clous.")[1] > > instead. > > This is not an issue in $5, as all text nodes are stored in a sequence > (which is flattened), and you return the first result of the flattened > sequence. > > -- > Jens Erat > Universität Konstanz > Kommunikations-, Infomations-, Medienzentrum (KIM) > Abteilung Basisdienste > D-78457 Konstanz > Mail: jens.erat at uni-konstanz.de >
FB
France Baril3 Mar 2016 19:23 #

Thanks for taking the time to look at this so quickly. I'm still unsure how #2 isn't a sequence if #3 is.

Anyhow, if it all works as intended, I'm fine with using a variable or () to make sure the returned nodes are cast into a sequence.

I'm just a bit surprised that text nodes and element nodes are returned differently.

Regards,

France

Quoted text · Christian Grün · 54 lines
On Wed, Mar 2, 2016 at 3:43 PM, Christian Grün <christian.gruen at gmail.com> wrote: > And a little addition: > > $node//text()[1] > > …is an abbreviation for… > > $node/descendant-or-self::node()/child::text()[1] > > However, you are probably looking for: > > $node/descendant::text()[1] > > It’s completely fine to use parentheseses, as in this case, your query > will exactly be rewritten as shown above. > > > > On Wed, Mar 2, 2016 at 8:28 PM, Jens Erat <jens.erat at uni-konstanz.de> > wrote: > > This is a matter of precedence. > > > >> <li>{ $node//text()[1] }</li> > > > > Has the meaning of "return all text nodes, that are in first position of > > their encapsulating element". Consider the intermediate result after > > partial evaluation to be something like > > > > ("allo!"[1], "Il pleut des clous."[1]) > > > > Applying parenthesis as you proposed in #4 resolves the issue: > > > >> <li>{ ($node//text())[1] }</li> > > > > resulting in > > > > ("allo!", "Il pleut des clous.")[1] > > > > instead. > > > > This is not an issue in $5, as all text nodes are stored in a sequence > > (which is flattened), and you return the first result of the flattened > > sequence. > > > > -- > > Jens Erat > > Universität Konstanz > > Kommunikations-, Infomations-, Medienzentrum (KIM) > > Abteilung Basisdienste > > D-78457 Konstanz > > Mail: jens.erat at uni-konstanz.de > > >
-- France Baril Architecte documentaire / Documentation architect france.baril at architextus.com
CG
Christian Grün4 Mar 2016 10:30 #
Quoted text · France Baril · 2 lines
> Thanks for taking the time to look at this so quickly. I'm still unsure how > #2 isn't a sequence if #3 is.

Do you mean the result of #2 and #3? All results (values) of XQuery expressions are "sequences" (with 0 or more items), so the result of #2 is a sequence as well.

Quoted text · France Baril · 2 lines
> I'm just a bit surprised that text nodes and element nodes are returned > differently.

This is actually not about text or element nodes, it’s about descendant vs. child axis:

The following two queries are identical:

  $node//text()[1]
  $node/descendant-or-self::node()/child::text()[1]

If evaluated, you will get the first child text node of all nodes of $node. In contrast..

  ($node//text())[1]
  $node/descendant::text()[1]

..will give you the first descendant text node of $node. Do you see the difference?

Hope this helps, Christian

FB
France Baril8 Mar 2016 22:24 #

Doh! Got it!

Thanks!

Quoted text · Christian Grün · 33 lines
On Fri, Mar 4, 2016 at 4:30 AM, Christian Grün <christian.gruen at gmail.com> wrote: > > Thanks for taking the time to look at this so quickly. I'm still unsure > how > > #2 isn't a sequence if #3 is. > > Do you mean the result of #2 and #3? All results (values) of XQuery > expressions are "sequences" (with 0 or more items), so the result of > #2 is a sequence as well. > > > I'm just a bit surprised that text nodes and element nodes are returned > > differently. > > This is actually not about text or element nodes, it’s about > descendant vs. child axis: > > The following two queries are identical: > > $node//text()[1] > $node/descendant-or-self::node()/child::text()[1] > > If evaluated, you will get the first child text node of all nodes of > $node. In contrast.. > > ($node//text())[1] > $node/descendant::text()[1] > > ..will give you the first descendant text node of $node. Do you see > the difference? > > Hope this helps, > Christian >
-- France Baril Architecte documentaire / Documentation architect france.baril at architextus.com

⚡Generated with XQuery