Discussion:
[xquery-talk] A flowering map
Ihe Onwuka
2014-01-01 07:02:51 UTC
Permalink
The code below should (it's been edited) use map to create an element for A
B C D within the parent reviewData.

The call to local:getReview is expensive though, so to avoid calling it
twice I am returning a sequence as the content of the element constructor.

xquery version "3.0";

declare variable $coll:='/db/apps/spark/';

declare function local:getReviews($type as xs:string+) as element(review)* {
$type ! collection($coll || .))/descendant::review
};

<stats date="{current-date()}">
<reviewData>{('','A','B','C','D') !
element {if (.) then . else 'total'}

{local:getReviews(.)/(count(.),count(distinct-values(thing/@link)))}</reviewData>}
</stats>

What I would like to do is cache the result of calling local:getReviews so
that I am not pushed into returning a sequence just so as to avoid multiple
expensive calls to local:getReviews.
David Lee
2014-01-01 15:01:14 UTC
Permalink
You need to put () around FLOWR expressions after a ! like

(1,2,3) ! ( for $a in . return . )


From: talk-***@x-query.com [mailto:talk-***@x-query.com] On Behalf Of Ihe Onwuka
Sent: Wednesday, January 01, 2014 2:03 AM
To: ***@x-query.com
Subject: [xquery-talk] A flowering map

The code below should (it's been edited) use map to create an element for A B C D within the parent reviewData.

The call to local:getReview is expensive though, so to avoid calling it twice I am returning a sequence as the content of the element constructor.

xquery version "3.0";

declare variable $coll:='/db/apps/spark/';

declare function local:getReviews($type as xs:string+) as element(review)* {
$type ! collection($coll || .))/descendant::review
};

<stats date="{current-date()}">
<reviewData>{('','A','B','C','D') !
element {if (.) then . else 'total'}
{local:getReviews(.)/(count(.),count(distinct-values(thing/@link)))}</reviewData>}
</stats>

What I would like to do is cache the result of calling local:getReviews so that I am not pushed into returning a sequence just so as to avoid multiple expensive calls to local:getReviews.
Ihe Onwuka
2014-01-02 08:32:39 UTC
Permalink
So now my code looks like

xquery version "3.0";

import module namespace sp="urn:sparkpictures.com" at 'common.xqm';

declare function local:getReviews($type as xs:string+) as element(review)* {
$type ! collection($sp:reviewsColl || '/' || .)/reviews/review
};

<stats date="{current-date()}">{

<reviewData>{('',$sp:tabs) !
(let $reviews:=local:getReviews(.)
return element {if (.) then . else 'total'}
{count($reviews)})}</reviewData>}
</stats>

where $sp:tabs just contains a sequence of strings. I have simplified it to
just return count($reviews) but the above code gives me

<?xml version="1.0"
?><exception><path>/db/apps/spark/stats.xq</path><message>err:XPDY0002
Post by David Lee
You need to put () around FLOWR expressions after a ! like
(1,2,3) ! ( for $a in . return . )
Behalf Of *Ihe Onwuka
*Sent:* Wednesday, January 01, 2014 2:03 AM
*Subject:* [xquery-talk] A flowering map
The code below should (it's been edited) use map to create an element for
A B C D within the parent reviewData.
The call to local:getReview is expensive though, so to avoid calling it
twice I am returning a sequence as the content of the element constructor.
xquery version "3.0";
declare variable $coll:='/db/apps/spark/';
declare function local:getReviews($type as xs:string+) as element(review)* {
$type ! collection($coll || .))/descendant::review
};
<stats date="{current-date()}">
<reviewData>{('','A','B','C','D') !
element {if (.) then . else 'total'}
</stats>
What I would like to do is cache the result of calling local:getReviews so
that I am not pushed into returning a sequence just so as to avoid multiple
expensive calls to local:getReviews.
Joe Wicentowski
2014-01-02 09:18:12 UTC
Permalink
I think you may have found a bug in eXist-db. Your code can be
reduced to the following tests:

Works in eXist-db:

('A','B','C','D') ! element {.} {'Z'}

Fails with the undefined static context error.

('A','B','C','D') ! (let $x := 1 return element {.} {'Z'})

You may wish to report this on exist-open.

Joe
Ihe Onwuka
2014-01-02 09:34:11 UTC
Permalink
yeah I was thinking that but y'know how it is when you go in all guns
blazing and claiming you've found a bug...... but now that you have
emboldened my keyboard I'm thinking of a subject heading like t will be
Bug. Fix it you b******ds.
Post by Joe Wicentowski
I think you may have found a bug in eXist-db. Your code can be
('A','B','C','D') ! element {.} {'Z'}
Fails with the undefined static context error.
('A','B','C','D') ! (let $x := 1 return element {.} {'Z'})
You may wish to report this on exist-open.
Joe
Liam R E Quin
2014-01-02 19:56:44 UTC
Permalink
Post by Joe Wicentowski
I think you may have found a bug in eXist-db. Your code can be
('A','B','C','D') ! element {.} {'Z'}
Fails with the undefined static context error.
('A','B','C','D') ! (let $x := 1 return element {.} {'Z'})
Both these examples work in BaseX for what it's worth (I just tried, at
least in "7.7beta").
--
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
The barefoot typographer
William Candillon
2014-01-01 18:52:20 UTC
Permalink
Hello,

I think that you are missing a return clause after the let clause.

William
Post by Ihe Onwuka
The code below should (it's been edited) use map to create an element for A
B C D within the parent reviewData.
The call to local:getReview is expensive though, so to avoid calling it
twice I am returning a sequence as the content of the element constructor.
xquery version "3.0";
declare variable $coll:='/db/apps/spark/';
declare function local:getReviews($type as xs:string+) as element(review)* {
$type ! collection($coll || .))/descendant::review
};
<stats date="{current-date()}">
<reviewData>{('','A','B','C','D') !
element {if (.) then . else 'total'}
</stats>
What I would like to do is cache the result of calling local:getReviews so
that I am not pushed into returning a sequence just so as to avoid multiple
expensive calls to local:getReviews.
Loading...