XQuery 3.1/Build array of maps dynamically
Tuesday, 12 December 2017 · 7 messages
HE
Hondros, Constantine (ELS-AMS)12 Dec 2017 13:16 #
Hello all,
I want to dynamically build a map where the value is an array of maps. I am having a problem with the syntax. (My use-case is to deliver this as JSON for simple ingestion to Spark, by the way).
Here's my test code, which translates cleanly into JSON:
declare option output:method 'json';
map {
"authors": [ map{"fn":"John", "ln":"Smith"}, map{"fn":"Jane", "ln":"Doe"} ]
}However, when I try to build the same map dynamically, I get the error "Value has more than one item". I guess this is because my for loop is returning a sequence, but I can't figure out the syntax to get it working. Any ideas?
declare option output:method 'json';
map {
"authors": [
(for $b in $authors return (: just assume $authors is populated ...:)
map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()})
]
}TIA!
________________________________
Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The Netherlands, Registration No. 33156677, Registered in The Netherlands.
CG
Christian Grün12 Dec 2017 13:20 #
Hi Constantine,
Quoted text · Hondros, Constantine (ELS-AMS) · 1 line
> (: just assume $authors is populated ...:)
Could you provide us with a little self-contained example? Because there are all kinds of populations out there.
TIA as well,
Christian
HE
Hondros, Constantine (ELS-AMS)12 Dec 2017 13:30 #
Hi Christian,
I was already kicking myself for rushing and not providing a SCE! Please see the code below, and thanks.
declare option output:method 'json';
declare variable $authors := <authors>
<author>
<given-name>Robert A</given-name>
<surname>Sanders</surname>
</author>
<author>
<given-name>Emily</given-name>
<surname>Chapel</surname>
</author>
</authors>;
map { "authors": [
(for $b in $authors/author return
map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()})
]
}
Quoted text · Christian Grün · 13 lines
-----Original Message----- From: Christian Grün [mailto:christian.gruen at gmail.com] Sent: 12 December 2017 13:20 To: Hondros, Constantine (ELS-AMS) Cc: basex-talk at mailman.uni-konstanz.de Subject: Re: [basex-talk] XQuery 3.1/Build array of maps dynamically *** External email: use caution *** Hi Constantine, > (: just assume $authors is populated ...:) Could you provide us with a little self-contained example? Because there are all kinds of populations out there. TIA as well, Christian Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The Netherlands, Registration No. 33156677, Registered in The Netherlands.
CG
Christian Grün12 Dec 2017 13:32 #
Thanks. Your query does not yield “Value has more than one item”, at least with the latest snapshot of BaseX. But maybe you are expecting another result?
Quoted text · Constantine (ELS-AMS) · 90 lines
On Tue, Dec 12, 2017 at 1:30 PM, Hondros, Constantine (ELS-AMS) <C.Hondros at elsevier.com> wrote: > Hi Christian, > > I was already kicking myself for rushing and not providing a SCE! Please see > the code below, and thanks. > > > > declare option output:method 'json'; > > > > declare variable $authors := <authors> > > <author> > > <given-name>Robert A</given-name> > > <surname>Sanders</surname> > > </author> > > <author> > > <given-name>Emily</given-name> > > <surname>Chapel</surname> > > </author> > > </authors>; > > > > map { > > "authors": [ > > (for $b in $authors/author return > > map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()}) > > ] > > } > > > > > > -----Original Message----- > From: Christian Grün [mailto:christian.gruen at gmail.com] > Sent: 12 December 2017 13:20 > To: Hondros, Constantine (ELS-AMS) > Cc: basex-talk at mailman.uni-konstanz.de > Subject: Re: [basex-talk] XQuery 3.1/Build array of maps dynamically > > > > *** External email: use caution *** > > > > > > > > Hi Constantine, > > > >> (: just assume $authors is populated ...:) > > > > Could you provide us with a little self-contained example? Because there are > all kinds of populations out there. > > > > TIA as well, > > Christian > > > ________________________________ > > Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The > Netherlands, Registration No. 33156677, Registered in The Netherlands.
MH
Quoted text · Constantine (ELS-AMS) · 37 lines
On 12.12.2017 13:30, Hondros, Constantine (ELS-AMS) wrote: > I was already kicking myself for rushing and not providing a SCE! Please > see the code below, and thanks. > > declare option output:method 'json'; > > declare variable $authors := <authors> > > <author> > > <given-name>Robert A</given-name> > > <surname>Sanders</surname> > > </author> > > <author> > > <given-name>Emily</given-name> > > <surname>Chapel</surname> > > </author> > > </authors>; > > map { > > "authors": [ > > (for $b in $authors/author return > > map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()}) > > ] > > }
I think to get the map structure from your earlier sample you want
declare option output:method 'json';
declare variable $authors := <authors>
<author>
<given-name>Robert A</given-name>
<surname>Sanders</surname>
</author>
<author>
<given-name>Emily</given-name>
<surname>Chapel</surname>
</author>
</authors>;
map {
"authors": array{$authors/author!map{"fn" : data(given-name), "ln"
: data(surname)}}}
Result is
{
"authors": [
{
"ln": "Sanders",
"fn": "Robert A"
},
{
"ln": "Chapel",
"fn": "Emily"
}
]
}CG
This time I was too quick, sorry (I ignored the query prolog of your query).
This is the fixed version:
declare namespace output = 'http://www.w3.org/2010/xslt-xquery-serialization';
declare option output:method 'json';
declare variable $authors :=
<authors>
<author>
<given-name>Robert A</given-name>
<surname>Sanders</surname>
</author>
<author>
<given-name>Emily</given-name>
<surname>Chapel</surname>
</author>
</authors>;
map {
"authors": array {
for $b in $authors/author
return map {
"fn": $b/*:given-name/text(),
"ln": $b/*:surname/text()
}
}
}Check out [1] to learn about the subtle difference betwen [] and array {}.
Best,
Christian
[1] http://docs.basex.org/wiki/XQuery_3.1#Arrays
Quoted text · Christian Grün · 97 lines
On Tue, Dec 12, 2017 at 1:32 PM, Christian Grün <christian.gruen at gmail.com> wrote: > Thanks. Your query does not yield “Value has more than one item”, at > least with the latest snapshot of BaseX. But maybe you are expecting > another result? > > > On Tue, Dec 12, 2017 at 1:30 PM, Hondros, Constantine (ELS-AMS) > <C.Hondros at elsevier.com> wrote: >> Hi Christian, >> >> I was already kicking myself for rushing and not providing a SCE! Please see >> the code below, and thanks. >> >> >> >> declare option output:method 'json'; >> >> >> >> declare variable $authors := <authors> >> >> <author> >> >> <given-name>Robert A</given-name> >> >> <surname>Sanders</surname> >> >> </author> >> >> <author> >> >> <given-name>Emily</given-name> >> >> <surname>Chapel</surname> >> >> </author> >> >> </authors>; >> >> >> >> map { >> >> "authors": [ >> >> (for $b in $authors/author return >> >> map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()}) >> >> ] >> >> } >> >> >> >> >> >> -----Original Message----- >> From: Christian Grün [mailto:christian.gruen at gmail.com] >> Sent: 12 December 2017 13:20 >> To: Hondros, Constantine (ELS-AMS) >> Cc: basex-talk at mailman.uni-konstanz.de >> Subject: Re: [basex-talk] XQuery 3.1/Build array of maps dynamically >> >> >> >> *** External email: use caution *** >> >> >> >> >> >> >> >> Hi Constantine, >> >> >> >>> (: just assume $authors is populated ...:) >> >> >> >> Could you provide us with a little self-contained example? Because there are >> all kinds of populations out there. >> >> >> >> TIA as well, >> >> Christian >> >> >> ________________________________ >> >> Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The >> Netherlands, Registration No. 33156677, Registered in The Netherlands.
HE
Hondros, Constantine (ELS-AMS)12 Dec 2017 14:08 #
Ah, fantastic. Thank you Christian (and Martin).
Yes, I was using an incorrect constructor for Arrays in this instance.
Many thanks,
Constantine
Quoted text · Christian Grün · 132 lines
-----Original Message----- From: Christian Grün [mailto:christian.gruen at gmail.com] Sent: 12 December 2017 13:41 To: Hondros, Constantine (ELS-AMS) Cc: basex-talk at mailman.uni-konstanz.de Subject: Re: [basex-talk] XQuery 3.1/Build array of maps dynamically *** External email: use caution *** This time I was too quick, sorry (I ignored the query prolog of your query). This is the fixed version: declare namespace output = 'http://www.w3.org/2010/xslt-xquery-serialization'; declare option output:method 'json'; declare variable $authors := <authors> <author> <given-name>Robert A</given-name> <surname>Sanders</surname> </author> <author> <given-name>Emily</given-name> <surname>Chapel</surname> </author> </authors>; map { "authors": array { for $b in $authors/author return map { "fn": $b/*:given-name/text(), "ln": $b/*:surname/text() } } } Check out [1] to learn about the subtle difference betwen [] and array {}. Best, Christian [1] http://docs.basex.org/wiki/XQuery_3.1#Arrays On Tue, Dec 12, 2017 at 1:32 PM, Christian Grün <christian.gruen at gmail.com> wrote: > Thanks. Your query does not yield “Value has more than one item”, at > least with the latest snapshot of BaseX. But maybe you are expecting > another result? > > > On Tue, Dec 12, 2017 at 1:30 PM, Hondros, Constantine (ELS-AMS) > <C.Hondros at elsevier.com> wrote: >> Hi Christian, >> >> I was already kicking myself for rushing and not providing a SCE! >> Please see the code below, and thanks. >> >> >> >> declare option output:method 'json'; >> >> >> >> declare variable $authors := <authors> >> >> <author> >> >> <given-name>Robert A</given-name> >> >> <surname>Sanders</surname> >> >> </author> >> >> <author> >> >> <given-name>Emily</given-name> >> >> <surname>Chapel</surname> >> >> </author> >> >> </authors>; >> >> >> >> map { >> >> "authors": [ >> >> (for $b in $authors/author return >> >> map{"fn":$b/*:given-name/text(), "ln":$b/*:surname/text()}) >> >> ] >> >> } >> >> >> >> >> >> -----Original Message----- >> From: Christian Grün [mailto:christian.gruen at gmail.com] >> Sent: 12 December 2017 13:20 >> To: Hondros, Constantine (ELS-AMS) >> Cc: basex-talk at mailman.uni-konstanz.de >> Subject: Re: [basex-talk] XQuery 3.1/Build array of maps dynamically >> >> >> >> *** External email: use caution *** >> >> >> >> >> >> >> >> Hi Constantine, >> >> >> >>> (: just assume $authors is populated ...:) >> >> >> >> Could you provide us with a little self-contained example? Because >> there are all kinds of populations out there. >> >> >> >> TIA as well, >> >> Christian >> >> >> ________________________________ >> >> Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The >> Netherlands, Registration No. 33156677, Registered in The Netherlands. Elsevier B.V. Registered Office: Radarweg 29, 1043 NX Amsterdam, The Netherlands, Registration No. 33156677, Registered in The Netherlands.
Written for BaseX 8.6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery