json-to-xml and xpath
Saturday, 26 August 2017 · 15 messages · last reply 18 Sep 2017
GD
Günter Dunz-Wolff26 Aug 2017 12:23 #
Dear all,
I’m trying to get data out of json via xquery.
This is my scenario:
1. Fetching data with
fetch:text() calling a REST-API
2. Transforming the data with json-to-xml, so I’ll get something like <array xmlns="http://www.w3.org/2005/xpath-functions“>
<map>
<string key=„word1“>gehen</string>
...
</map>
...
</array>
3. In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json)
4. I try to get „gehen“ with $json_xml//string[@key='word1‘], but it yields nothing, also $json_xml//string yields nothing. Only $json_xml//text() yields all string-values into a long string.
What am I doing wrong? Or is there another way, to work with JSON-Data to get values of a given key?
Thanks in advance,
GünterMH
Martin Honnen26 Aug 2017 12:26 #
Quoted text · Günter Dunz-Wolff · 16 lines
On 26.08.2017 12:23, Günter Dunz-Wolff wrote: > I’m trying to get data out of json via xquery. > This is my scenario: > 1. Fetching data with fetch:text() calling a REST-API > 2. Transforming the data with json-to-xml, so I’ll get something like > <array xmlns="http://www.w3.org/2005/xpath-functions“> > <map> > <string key=„word1“>gehen</string> > ... > </map> > ... > </array> > 3. In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json) > 4. I try to get „gehen“ with $json_xml//string[@key='word1‘], but it yields nothing, also $json_xml//string yields nothing. Only $json_xml//text() yields all string-values into a long string. > > What am I doing wrong? Or is there another way, to work with JSON-Data to get values of a given key?
The elements are in the namespace http://www.w3.org/2005/xpath-functions so either use
$json_xml//*:string[@key='word1']
or make sure you declare a prefix (e.g. 'fn') for the namespace and use that prefix in e.g.
$json_xml//
fn:string[@key='word1']GD
Günter Dunz-Wolff26 Aug 2017 12:36 #
It works. I’ll go with the second solution. Martin, thanks a lot!
Quoted text · Martin Honnen · 24 lines
> Am 26.08.2017 um 12:26 schrieb Martin Honnen <martin.honnen at gmx.de>: > > On 26.08.2017 12:23, Günter Dunz-Wolff wrote: > >> I’m trying to get data out of json via xquery. >> This is my scenario: >> 1. Fetching data with fetch:text() calling a REST-API >> 2. Transforming the data with json-to-xml, so I’ll get something like >> <array xmlns="http://www.w3.org/2005/xpath-functions“> >> <map> >> <string key=„word1“>gehen</string> >> ... >> </map> >> ... >> </array> >> 3. In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json) >> 4. I try to get „gehen“ with $json_xml//string[@key='word1‘], but it yields nothing, also $json_xml//string yields nothing. Only $json_xml//text() yields all string-values into a long string. >> What am I doing wrong? Or is there another way, to work with JSON-Data to get values of a given key? > > The elements are in the namespace http://www.w3.org/2005/xpath-functions so either use > $json_xml//*:string[@key='word1'] > or make sure you declare a prefix (e.g. 'fn') for the namespace and use that prefix in e.g. > $json_xml//fn:string[@key='word1'] >
HR
Hans-Juergen Rennau26 Aug 2017 15:53 #
Hi Günter, have you considered using
json:parse
instead? I find the W3C-defined format obtained from fn:json-to-xml unnatural and unpractical; whereas BaseX-defined json:parse produces a very elegant, intuitive and natural representation of the content - turning JSON documents into near-equivalents of XML documents. Consider this example: given the json shown at the end of this post, getting a simple report (list of flight destinations and times) using json:parse might looks like this: unparsed-text('flights.json') ! json:parse(.)
// flight[departureAirport = 'CGN']/concat(arrivalAirport, ' ', departureTime)
In comparison, using fn:json-to-xml, my query looks like this: unparsed-text('flights.json') ! json-to-xml(.)
// *:map[@key eq 'flight'][*:string[@key = 'departureAirport'] = 'CGN'] /concat(*:string[@key = 'arrivalAirport'], ' ', *:string[@key = 'departureTime'])
Kind regards,Hans-Jürgen[
{
"flight" : {
"departureAirport" : "CGN",
"arrivalAirport" : "JFK",
"departureTime" : "2017-08-26T20:00:00"
}
},
{
"flight" : {
"departureAirport" : "CGN",
"arrivalAirport" : "FRA",
"departureTime" : "2017-08-26T21:00:00"
}
}
]Quoted text · Günter Dunz-Wolff · 1 line
Günter Dunz-Wolff <guenter.dunzwolff at gmail.com> schrieb am 12:36 Samstag, 26.August 2017:
It works. I’ll go with the second solution. Martin, thanks a lot!
Quoted text · Günter Dunz-Wolff · 24 lines
> Am 26.08.2017 um 12:26 schrieb Martin Honnen <martin.honnen at gmx.de>: > > On 26.08.2017 12:23, Günter Dunz-Wolff wrote: > >> I’m trying to get data out of json via xquery. >> This is my scenario: >> 1. Fetching data with fetch:text() calling a REST-API >> 2. Transforming the data with json-to-xml, so I’ll get something like >> <array xmlns="http://www.w3.org/2005/xpath-functions“> >> <map> >> <string key=„word1“>gehen</string> >> ... >> </map> >> ... >> </array> >> 3. In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json) >> 4. I try to get „gehen“ with $json_xml//string[@key='word1‘], but it yields nothing, also $json_xml//string yields nothing. Only $json_xml//text() yields all string-values into a long string. >> What am I doing wrong? Or is there another way, to work with JSON-Data to get values of a given key? > > The elements are in the namespace http://www.w3.org/2005/xpath-functions so either use > $json_xml//*:string[@key='word1'] > or make sure you declare a prefix (e.g. 'fn') for the namespace and use that prefix in e.g. > $json_xml//fn:string[@key='word1'] >
HR
Of course, Liam, but of course the BaseX format has its escaping rules, so that it works *always*. The names become less beautiful here and there, but in practise a couple of warped names among hundreds of nice and meaningful ones are better than meaningless names throughout. A document with element names being "map", "array", "string", "number", "boolen", "number" and "null" is totally at odds with the goal to *express* information in a natural and intuitive way. (It's like ordering "liquid matter (named beer) and solid matter (named Bratwurst), politeness token (named please)", instead of "A beer and a Bratwurst, please." Nota bene, "ordinary" messages and "ordinary" configurations speak XML compatible names more or less exclusively. If one has to *work* with JSON data (extractions, transformations, reporting), it would be downright eccentric to opt for the W3C format if you have access to the BaseX one. I hope the W3C will come up with a meaningful format definition, comparable to the BaseX one. The importance for the scope of XQuery applicability cannot be overestimated.
Kind regards,Hans-Jürgen
Quoted text · Hans-Juergen Rennau · 4 lines
Liam R. E. Quin <liam at w3.org> schrieb am 22:02 Samstag, 26.August 2017: On Sat, 2017-08-26 at 13:53 +0000, Hans-Juergen Rennau wrote: > I find the W3C-defined format obtained from fn:json-to-xml > unnatural and unpractical;
It is, but it works in more cases. JSON keys can have values that
aren't possible XML element names, e.g.
{
"1" : "one",
"2" : "two",
"*" : "lots"
}--
Liam Quin, W3C, http://www.w3.org/People/Quin/
Staff contact for Verifiable Claims WG, XQuery WG
Web slave for http://www.fromoldbooks.org/
LQ
Quoted text · Hans-Juergen Rennau · 3 lines
On Sat, 2017-08-26 at 13:53 +0000, Hans-Juergen Rennau wrote: > I find the W3C-defined format obtained from fn:json-to-xml > unnatural and unpractical;
It is, but it works in more cases. JSON keys can have values that
aren't possible XML element names, e.g.
{
"1" : "one",
"2" : "two",
"*" : "lots"
}--
Liam Quin, W3C, http://www.w3.org/People/Quin/
Staff contact for Verifiable Claims WG, XQuery WG
Web slave for http://www.fromoldbooks.org/
LQ
Quoted text · Hans-Juergen Rennau · 6 lines
On Sat, 2017-08-26 at 20:35 +0000, Hans-Juergen Rennau wrote: > Of course, Liam, but of course the BaseX format has its escaping > rules, so that it works *always*. The names become less beautiful > here and there, but in practise a couple of warped names among > hundreds of nice and meaningful ones are better than meaningless > names throughout.
It's subjective I think. We did have some feedback on the design of the XML/XDM representation for JSON.
[...]
Quoted text · Hans-Juergen Rennau · 2 lines
>I hope the W3C will come up with a meaningful format > definition, comparable to the BaseX one.
I don't see that happening - the XQuery and XSLT work is essentially finished except for bug fixes at this point.
It might happen in the expath community group, if people show up to do it - remember, W3C specs are essentially done by volunteers.
Liam
--
Liam Quin, W3C, http://www.w3.org/People/Quin/
Staff contact for Verifiable Claims WG, XQuery WG
Web slave for http://www.fromoldbooks.org/
R
Hi,
I want to use the apply function within an updating webfunction, see[1] How can this be done?
TIA,
Rob Stapper
[1]
declare
%rest:path("/cFactBank/dbCreate")
%rest:PUT("{$dataRec}")
%input:json("format=map")
%updating
function _:cFactBank.dbCreate
( $dataRec as array(*)
)
{
apply( db:create#1
, $dataRec
)
} ;MS
Michael Seiferle28 Aug 2017 18:20 #
Hi Rob,
may I ask what you intented to do? Looks like you expect $dataRec to contain exactly one value, right? At least I think so because you called
db:create#1 in fn:apply which implies you expect the array to contain a single value.
To create a single database use:Quoted text · r.stapper · 3 lines
> ``` > db:create($dataRec => array:get(1)) > ```
…or… if you want to create a database for each of the array values:
Quoted text · r.stapper · 2 lines
> for $db in ($dataRec => array:flatten()) (: Flatten array to a sequence :) > return db:create($db). (: create one database per array item :)
…and… last but not least, for "Dynamic Updating Function Invocation“[1] you might use:
Quoted text · r.stapper · 3 lines
> let $create := db:create#1 > for $db in ($dataRec => array:flatten()) > return invoke updating $create($db)
I could not wrap my head around using
array:for-each(#2) and dynamic updating function invocation; this could make for a more readable solution, but I can not seem to get the syntax right; if we already fully support it at all ;-)
I hope I did not get you all wrong, feel free to ask for more help! ;-)
Best
Michael
[1] https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation <https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation>Quoted text · r.stapper · 26 lines
> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: > > Hi, > > I want to use the apply function within an updating webfunction, see[1] > How can this be done? > > TIA, > > Rob Stapper > > [1] > declare > %rest:path("/cFactBank/dbCreate") > %rest:PUT("{$dataRec}") > %input:json("format=map") > > %updating > function _:cFactBank.dbCreate > ( $dataRec as array(*) > ) > { > apply( db:create#1 > , $dataRec > ) > } ;
R
r.stapper29 Aug 2017 08:06 #
Hi Michael,
Th point is that I am looking for a generic solution which I thought I had found with the use of the apply-function.
Most of my webservices take a record with more than one fieldvalue. By putting the fieldvalues in an json-formatted array on the client side and the use of the apply-function on the serverside, see [1], I thought I had found a nice and clean generic solution. Unfortunately this soultion gives me the error: "Function body must be an updating expression".
The issue is that the error is, in my opinion, falsely triggered by the use of the apply-function within updating function. An
updating-error-situation should, in my opinion, be determined based on the function that is called by the apply function. In this case though the apply function calls an updating function, Basex still triggeres an updating error.
I cann't use MIXEDUPDATES because my webservices are in a module.
I really would like to use the apply-function here. What to do?
[1]
declare
%rest:path("/cFactBank/request/new")
%rest:PUT("{$dataRec}")
%input:json("format=map")
%updating
function _:request.new
( $dataRec as array(*)
)
{
apply( request:new#6
, $dataRec
)
} ;Greetings,
Rob
Quoted text · Michael Seiferle · 70 lines
Michael Seiferle schreef op 28.08.2017 18:20: > Hi Rob, > > may I ask what you intented to do? Looks like you expect $dataRec to > contain exactly one value, right? > At least I think so because you called `db:create#1` in `fn:apply` > which implies you expect the array to contain a single value. > > To create a single database use: > >> ``` >> db:create($dataRec => array:get(1)) >> ``` > > …or… if you want to create a database for each of the array > values: > >> for $db in ($dataRec => array:flatten()) (: Flatten array to a >> sequence :) >> return db:create($db). (: create one >> database per array item :) > > …and… last but not least, for "Dynamic Updating Function > Invocation“[1] you might use: > >> let $create := db:create#1 >> for $db in ($dataRec => array:flatten()) >> return invoke updating $create($db) > > I could not wrap my head around using array:for-each(#2) and dynamic > updating function invocation; this could make for a more readable > solution, but I can not seem to get the syntax right; if we already > fully support it at all ;-) > > I hope I did not get you all wrong, feel free to ask for more help! > ;-) > > Best > Michael > > [1] > https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation > >> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >> >> Hi, >> >> I want to use the apply function within an updating webfunction, >> see[1] >> How can this be done? >> >> TIA, >> >> Rob Stapper >> >> [1] >> declare >> %rest:path("/cFactBank/dbCreate") >> %rest:PUT("{$dataRec}") >> %input:json("format=map") >> >> %updating >> function _:cFactBank.dbCreate >> ( $dataRec as array(*) >> ) >> { >> apply( db:create#1 >> , $dataRec >> ) >> } ;
R
r.stapper29 Aug 2017 15:07 #
Hi Michael,
Though the GUI still gives an error onth the use of the apply-function within an updating function, my webservices do work correctly. Just added the
MIXUPDATES-option in the web.xml file.
Best Rob.
-------- Oorspronkelijke bericht --------
Onderwerp: Re: [basex-talk] using apply-function within an updating function
Datum: 29.08.2017 08:06
Afzender: r.stapper at lijbrandt.nl
Ontvanger: Michael Seiferle <ms at basex.org>
Kopie: BaseX <basex-talk at mailman.uni-konstanz.de>
Hi Michael,
Th point is that I am looking for a generic solution which I thought I had found with the use of the apply-function.
Most of my webservices take a record with more than one fieldvalue. By putting the fieldvalues in an json-formatted array on the client side and the use of the apply-function on the serverside, see [1], I thought I had found a nice and clean generic solution. Unfortunately this soultion gives me the error: "Function body must be an updating expression".
The issue is that the error is, in my opinion, falsely triggered by the use of the apply-function within updating function. An
updating-error-situation should, in my opinion, be determined based on the function that is called by the apply function. In this case though the apply function calls an updating function, Basex still triggeres an updating error.
I cann't use MIXEDUPDATES because my webservices are in a module.
I really would like to use the apply-function here. What to do?
[1]
declare
%rest:path("/cFactBank/request/new")
%rest:PUT("{$dataRec}")
%input:json("format=map") %updating
function _:request.new
( $dataRec as array(*)
)
{
apply( request:new#6
, $dataRec
)
} ;Greetings,
Rob
Quoted text · r.stapper · 70 lines
Michael Seiferle schreef op 28.08.2017 18:20: > Hi Rob, > > may I ask what you intented to do? Looks like you expect $dataRec to > contain exactly one value, right? > At least I think so because you called `db:create#1` in `fn:apply` > which implies you expect the array to contain a single value. > > To create a single database use: > >> ``` >> db:create($dataRec => array:get(1)) >> ``` > > …or… if you want to create a database for each of the array > values: > >> for $db in ($dataRec => array:flatten()) (: Flatten array to a >> sequence :) >> return db:create($db). (: create one >> database per array item :) > > …and… last but not least, for "Dynamic Updating Function > Invocation“[1] you might use: > >> let $create := db:create#1 >> for $db in ($dataRec => array:flatten()) >> return invoke updating $create($db) > > I could not wrap my head around using array:for-each(#2) and dynamic > updating function invocation; this could make for a more readable > solution, but I can not seem to get the syntax right; if we already > fully support it at all ;-) > > I hope I did not get you all wrong, feel free to ask for more help! > ;-) > > Best > Michael > > [1] > https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation > >> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >> >> Hi, >> >> I want to use the apply function within an updating webfunction, >> see[1] >> How can this be done? >> >> TIA, >> >> Rob Stapper >> >> [1] >> declare >> %rest:path("/cFactBank/dbCreate") >> %rest:PUT("{$dataRec}") >> %input:json("format=map") >> >> %updating >> function _:cFactBank.dbCreate >> ( $dataRec as array(*) >> ) >> { >> apply( db:create#1 >> , $dataRec >> ) >> } ;
ML
Marco Lettere29 Aug 2017 15:17 #
Hi Rob,
I suppose that if you add MIXUPDATES=true below #LOCAL OPTIONS in the .basex file that you will find in your basex install directory and restart your GUI, the error will not show up any longer in the GUI itself.
Regards,
Marco.
Quoted text · r.stapper at lijbrandt.nl · 131 lines
On 29/08/2017 15:07, r.stapper at lijbrandt.nl wrote: > Hi Michael, > > Though the GUI still gives an error onth the use of the apply-function > within an updating function, my webservices do work correctly. Just > added the MIXUPDATES-option in the web.xml file. > > Best Rob. > > -------- Oorspronkelijke bericht -------- > Onderwerp: Re: [basex-talk] using apply-function within an updating > function > Datum: 29.08.2017 08:06 > Afzender: r.stapper at lijbrandt.nl > Ontvanger: Michael Seiferle <ms at basex.org> > Kopie: BaseX <basex-talk at mailman.uni-konstanz.de> > > Hi Michael, > > Th point is that I am looking for a generic solution which I thought I > had found with the use of the apply-function. > Most of my webservices take a record with more than one fieldvalue. By > putting the fieldvalues in an json-formatted array on the client side > and the use of the apply-function on the serverside, see [1], I > thought I had found a nice and clean generic solution. Unfortunately > this soultion gives me the error: "Function body must be an updating > expression". > > The issue is that the error is, in my opinion, falsely triggered by > the use of the apply-function within updating function. An > updating-error-situation should, in my opinion, be determined based on > the function that is called by the apply function. In this case though > the apply function calls an updating function, Basex still triggeres > an updating error. > > I cann't use MIXEDUPDATES because my webservices are in a module. > > I really would like to use the apply-function here. What to do? > > [1] > declare > %rest:path("/cFactBank/request/new") > %rest:PUT("{$dataRec}") > %input:json("format=map") > > %updating > function _:request.new > ( $dataRec as array(*) > ) > { > apply( request:new#6 > , $dataRec > ) > } ; > > > Greetings, > Rob > > > Michael Seiferle schreef op 28.08.2017 18:20: >> Hi Rob, >> >> may I ask what you intented to do? Looks like you expect $dataRec to >> contain exactly one value, right? >> At least I think so because you called `db:create#1` in `fn:apply` >> which implies you expect the array to contain a single value. >> >> To create a single database use: >> >>> ``` >>> db:create($dataRec => array:get(1)) >>> ``` >> >> …or… if you want to create a database for each of the array >> values: >> >>> for $db in ($dataRec => array:flatten()) (: Flatten array to a >>> sequence :) >>> return db:create($db). (: create one >>> database per array item :) >> >> …and… last but not least, for "Dynamic Updating Function >> Invocation“[1] you might use: >> >>> let $create := db:create#1 >>> for $db in ($dataRec => array:flatten()) >>> return invoke updating $create($db) >> >> I could not wrap my head around using array:for-each(#2) and dynamic >> updating function invocation; this could make for a more readable >> solution, but I can not seem to get the syntax right; if we already >> fully support it at all ;-) >> >> I hope I did not get you all wrong, feel free to ask for more help! >> ;-) >> >> Best >> Michael >> >> [1] >> https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation >> >> >>> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >>> >>> Hi, >>> >>> I want to use the apply function within an updating webfunction, >>> see[1] >>> How can this be done? >>> >>> TIA, >>> >>> Rob Stapper >>> >>> [1] >>> declare >>> %rest:path("/cFactBank/dbCreate") >>> %rest:PUT("{$dataRec}") >>> %input:json("format=map") >>> >>> %updating >>> function _:cFactBank.dbCreate >>> ( $dataRec as array(*) >>> ) >>> { >>> apply( db:create#1 >>> , $dataRec >>> ) >>> } ;
MS
Michael Seiferle29 Aug 2017 21:08 #
Hi Rob,
hi Marco,
First: sorry for not coming back to you earlier.
Glad it worked using mixupdates, but I think there might be a way to make it work using the new XQUF 3.0 "invoke updating" capabilities :-) Christian is currently on holiday, I am sure he will report back on this.
Best from Konstanz,
Michael
Von meinem iPhone gesendet
Quoted text · Marco Lettere · 125 lines
> Am 29.08.2017 um 15:17 schrieb Marco Lettere <m.lettere at gmail.com>: > > Hi Rob, > I suppose that if you add MIXUPDATES=true below #LOCAL OPTIONS in the .basex file that you will find in your basex install directory and restart your GUI, the error will not show up any longer in the GUI itself. > Regards, > Marco. > >> On 29/08/2017 15:07, r.stapper at lijbrandt.nl wrote: >> Hi Michael, >> >> Though the GUI still gives an error onth the use of the apply-function within an updating function, my webservices do work correctly. Just added the MIXUPDATES-option in the web.xml file. >> >> Best Rob. >> >> -------- Oorspronkelijke bericht -------- >> Onderwerp: Re: [basex-talk] using apply-function within an updating function >> Datum: 29.08.2017 08:06 >> Afzender: r.stapper at lijbrandt.nl >> Ontvanger: Michael Seiferle <ms at basex.org> >> Kopie: BaseX <basex-talk at mailman.uni-konstanz.de> >> >> Hi Michael, >> >> Th point is that I am looking for a generic solution which I thought I had found with the use of the apply-function. >> Most of my webservices take a record with more than one fieldvalue. By putting the fieldvalues in an json-formatted array on the client side and the use of the apply-function on the serverside, see [1], I thought I had found a nice and clean generic solution. Unfortunately this soultion gives me the error: "Function body must be an updating expression". >> >> The issue is that the error is, in my opinion, falsely triggered by the use of the apply-function within updating function. An updating-error-situation should, in my opinion, be determined based on the function that is called by the apply function. In this case though the apply function calls an updating function, Basex still triggeres an updating error. >> >> I cann't use MIXEDUPDATES because my webservices are in a module. >> >> I really would like to use the apply-function here. What to do? >> >> [1] >> declare >> %rest:path("/cFactBank/request/new") >> %rest:PUT("{$dataRec}") >> %input:json("format=map") >> >> %updating >> function _:request.new >> ( $dataRec as array(*) >> ) >> { >> apply( request:new#6 >> , $dataRec >> ) >> } ; >> >> >> Greetings, >> Rob >> >> >> Michael Seiferle schreef op 28.08.2017 18:20: >>> Hi Rob, >>> >>> may I ask what you intented to do? Looks like you expect $dataRec to >>> contain exactly one value, right? >>> At least I think so because you called `db:create#1` in `fn:apply` >>> which implies you expect the array to contain a single value. >>> >>> To create a single database use: >>> >>>> ``` >>>> db:create($dataRec => array:get(1)) >>>> ``` >>> >>> …or… if you want to create a database for each of the array >>> values: >>> >>>> for $db in ($dataRec => array:flatten()) (: Flatten array to a >>>> sequence :) >>>> return db:create($db). (: create one >>>> database per array item :) >>> >>> …and… last but not least, for "Dynamic Updating Function >>> Invocation“[1] you might use: >>> >>>> let $create := db:create#1 >>>> for $db in ($dataRec => array:flatten()) >>>> return invoke updating $create($db) >>> >>> I could not wrap my head around using array:for-each(#2) and dynamic >>> updating function invocation; this could make for a more readable >>> solution, but I can not seem to get the syntax right; if we already >>> fully support it at all ;-) >>> >>> I hope I did not get you all wrong, feel free to ask for more help! >>> ;-) >>> >>> Best >>> Michael >>> >>> [1] >>> https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation >>> >>>> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >>>> >>>> Hi, >>>> >>>> I want to use the apply function within an updating webfunction, >>>> see[1] >>>> How can this be done? >>>> >>>> TIA, >>>> >>>> Rob Stapper >>>> >>>> [1] >>>> declare >>>> %rest:path("/cFactBank/dbCreate") >>>> %rest:PUT("{$dataRec}") >>>> %input:json("format=map") >>>> >>>> %updating >>>> function _:cFactBank.dbCreate >>>> ( $dataRec as array(*) >>>> ) >>>> { >>>> apply( db:create#1 >>>> , $dataRec >>>> ) >>>> } ; > >
RS
Rob Stapper30 Aug 2017 07:37 #
Hi Michael and Marco,
Thanx for the feedback.
@Marco, setting
MIXUPDATES is an efficient work around for suppressing the error message but the cost is that you lose the updating-checks completely. Updating-checks are very useful. @Michael, I'll dive into the XQUF 3.0. Sounds interesting.
Fact stays that the updating check doesn't work, as I see it, properly on the apply-function. Something for Christian to dive into when he is back on holidays ;-)
Again thanx for the replies.
Have fun,
Rob
-----Oorspronkelijk bericht-----Quoted text · basex-talk-bounces at mailman.uni-konstanz.de · 137 lines
Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at mailman.uni-konstanz.de] Namens Michael Seiferle Verzonden: dinsdag 29 augustus 2017 21:08 Aan: Marco Lettere CC: basex-talk at mailman.uni-konstanz.de Onderwerp: Re: [basex-talk] Fwd: Re: using apply-function within an updating function Hi Rob, hi Marco, First: sorry for not coming back to you earlier. Glad it worked using mixupdates, but I think there might be a way to make it work using the new XQUF 3.0 "invoke updating" capabilities :-) Christian is currently on holiday, I am sure he will report back on this. Best from Konstanz, Michael Von meinem iPhone gesendet > Am 29.08.2017 um 15:17 schrieb Marco Lettere <m.lettere at gmail.com>: > > Hi Rob, > I suppose that if you add MIXUPDATES=true below #LOCAL OPTIONS in the .basex file that you will find in your basex install directory and restart your GUI, the error will not show up any longer in the GUI itself. > Regards, > Marco. > >> On 29/08/2017 15:07, r.stapper at lijbrandt.nl wrote: >> Hi Michael, >> >> Though the GUI still gives an error onth the use of the apply-function within an updating function, my webservices do work correctly. Just added the MIXUPDATES-option in the web.xml file. >> >> Best Rob. >> >> -------- Oorspronkelijke bericht -------- >> Onderwerp: Re: [basex-talk] using apply-function within an updating >> function >> Datum: 29.08.2017 08:06 >> Afzender: r.stapper at lijbrandt.nl >> Ontvanger: Michael Seiferle <ms at basex.org> >> Kopie: BaseX <basex-talk at mailman.uni-konstanz.de> >> >> Hi Michael, >> >> Th point is that I am looking for a generic solution which I thought I had found with the use of the apply-function. >> Most of my webservices take a record with more than one fieldvalue. By putting the fieldvalues in an json-formatted array on the client side and the use of the apply-function on the serverside, see [1], I thought I had found a nice and clean generic solution. Unfortunately this soultion gives me the error: "Function body must be an updating expression". >> >> The issue is that the error is, in my opinion, falsely triggered by the use of the apply-function within updating function. An updating-error-situation should, in my opinion, be determined based on the function that is called by the apply function. In this case though the apply function calls an updating function, Basex still triggeres an updating error. >> >> I cann't use MIXEDUPDATES because my webservices are in a module. >> >> I really would like to use the apply-function here. What to do? >> >> [1] >> declare >> %rest:path("/cFactBank/request/new") >> %rest:PUT("{$dataRec}") >> %input:json("format=map") >> >> %updating >> function _:request.new >> ( $dataRec as array(*) >> ) >> { >> apply( request:new#6 >> , $dataRec >> ) >> } ; >> >> >> Greetings, >> Rob >> >> >> Michael Seiferle schreef op 28.08.2017 18:20: >>> Hi Rob, >>> >>> may I ask what you intented to do? Looks like you expect $dataRec to >>> contain exactly one value, right? >>> At least I think so because you called `db:create#1` in `fn:apply` >>> which implies you expect the array to contain a single value. >>> >>> To create a single database use: >>> >>>> ``` >>>> db:create($dataRec => array:get(1)) ``` >>> >>> …or… if you want to create a database for each of the array >>> values: >>> >>>> for $db in ($dataRec => array:flatten()) (: Flatten array to a >>>> sequence :) >>>> return db:create($db). (: create one >>>> database per array item :) >>> >>> …and… last but not least, for "Dynamic Updating Function >>> Invocation“[1] you might use: >>> >>>> let $create := db:create#1 >>>> for $db in ($dataRec => array:flatten()) return invoke updating >>>> $create($db) >>> >>> I could not wrap my head around using array:for-each(#2) and dynamic >>> updating function invocation; this could make for a more readable >>> solution, but I can not seem to get the syntax right; if we already >>> fully support it at all ;-) >>> >>> I hope I did not get you all wrong, feel free to ask for more help! >>> ;-) >>> >>> Best >>> Michael >>> >>> [1] >>> https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function >>> -invocation >>> >>>> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >>>> >>>> Hi, >>>> >>>> I want to use the apply function within an updating webfunction, >>>> see[1] How can this be done? >>>> >>>> TIA, >>>> >>>> Rob Stapper >>>> >>>> [1] >>>> declare >>>> %rest:path("/cFactBank/dbCreate") >>>> %rest:PUT("{$dataRec}") >>>> %input:json("format=map") >>>> >>>> %updating >>>> function _:cFactBank.dbCreate >>>> ( $dataRec as array(*) >>>> ) >>>> { >>>> apply( db:create#1 >>>> , $dataRec >>>> ) >>>> } ; > >
CG
Christian Grün18 Sep 2017 15:35 #
Hi Rob,
the official XQuery functions are limited to non-updating function arguments. Enabling
MIXUPDATES is the only way out, because you would otherwise be able to write code that is both updating and
non-updating: for $f in (db:output#1, count#1)
return apply($f, [1])Hope this helps,
Christian
Quoted text · Rob Stapper · 165 lines
On Wed, Aug 30, 2017 at 7:37 AM, Rob Stapper <r.stapper at lijbrandt.nl> wrote: > Hi Michael and Marco, > > Thanx for the feedback. > > @Marco, setting MIXUPDATES is an efficient work around for suppressing the error message but the cost is that you lose the updating-checks completely. Updating-checks are very useful. > @Michael, I'll dive into the XQUF 3.0. Sounds interesting. > > Fact stays that the updating check doesn't work, as I see it, properly on the apply-function. Something for Christian to dive into when he is back on holidays ;-) > > Again thanx for the replies. > > Have fun, > > Rob > > > -----Oorspronkelijk bericht----- > Van: basex-talk-bounces at mailman.uni-konstanz.de [mailto:basex-talk-bounces at mailman.uni-konstanz.de] Namens Michael Seiferle > Verzonden: dinsdag 29 augustus 2017 21:08 > Aan: Marco Lettere > CC: basex-talk at mailman.uni-konstanz.de > Onderwerp: Re: [basex-talk] Fwd: Re: using apply-function within an updating function > > Hi Rob, > hi Marco, > > > First: sorry for not coming back to you earlier. > > Glad it worked using mixupdates, but I think there might be a way to make it work using the new XQUF 3.0 "invoke updating" capabilities :-) Christian is currently on holiday, I am sure he will report back on this. > > > Best from Konstanz, > > Michael > > Von meinem iPhone gesendet > >> Am 29.08.2017 um 15:17 schrieb Marco Lettere <m.lettere at gmail.com>: >> >> Hi Rob, >> I suppose that if you add MIXUPDATES=true below #LOCAL OPTIONS in the .basex file that you will find in your basex install directory and restart your GUI, the error will not show up any longer in the GUI itself. >> Regards, >> Marco. >> >>> On 29/08/2017 15:07, r.stapper at lijbrandt.nl wrote: >>> Hi Michael, >>> >>> Though the GUI still gives an error onth the use of the apply-function within an updating function, my webservices do work correctly. Just added the MIXUPDATES-option in the web.xml file. >>> >>> Best Rob. >>> >>> -------- Oorspronkelijke bericht -------- >>> Onderwerp: Re: [basex-talk] using apply-function within an updating >>> function >>> Datum: 29.08.2017 08:06 >>> Afzender: r.stapper at lijbrandt.nl >>> Ontvanger: Michael Seiferle <ms at basex.org> >>> Kopie: BaseX <basex-talk at mailman.uni-konstanz.de> >>> >>> Hi Michael, >>> >>> Th point is that I am looking for a generic solution which I thought I had found with the use of the apply-function. >>> Most of my webservices take a record with more than one fieldvalue. By putting the fieldvalues in an json-formatted array on the client side and the use of the apply-function on the serverside, see [1], I thought I had found a nice and clean generic solution. Unfortunately this soultion gives me the error: "Function body must be an updating expression". >>> >>> The issue is that the error is, in my opinion, falsely triggered by the use of the apply-function within updating function. An updating-error-situation should, in my opinion, be determined based on the function that is called by the apply function. In this case though the apply function calls an updating function, Basex still triggeres an updating error. >>> >>> I cann't use MIXEDUPDATES because my webservices are in a module. >>> >>> I really would like to use the apply-function here. What to do? >>> >>> [1] >>> declare >>> %rest:path("/cFactBank/request/new") >>> %rest:PUT("{$dataRec}") >>> %input:json("format=map") >>> >>> %updating >>> function _:request.new >>> ( $dataRec as array(*) >>> ) >>> { >>> apply( request:new#6 >>> , $dataRec >>> ) >>> } ; >>> >>> >>> Greetings, >>> Rob >>> >>> >>> Michael Seiferle schreef op 28.08.2017 18:20: >>>> Hi Rob, >>>> >>>> may I ask what you intented to do? Looks like you expect $dataRec to >>>> contain exactly one value, right? >>>> At least I think so because you called `db:create#1` in `fn:apply` >>>> which implies you expect the array to contain a single value. >>>> >>>> To create a single database use: >>>> >>>>> ``` >>>>> db:create($dataRec => array:get(1)) ``` >>>> >>>> …or… if you want to create a database for each of the array >>>> values: >>>> >>>>> for $db in ($dataRec => array:flatten()) (: Flatten array to a >>>>> sequence :) >>>>> return db:create($db). (: create one >>>>> database per array item :) >>>> >>>> …and… last but not least, for "Dynamic Updating Function >>>> Invocation“[1] you might use: >>>> >>>>> let $create := db:create#1 >>>>> for $db in ($dataRec => array:flatten()) return invoke updating >>>>> $create($db) >>>> >>>> I could not wrap my head around using array:for-each(#2) and dynamic >>>> updating function invocation; this could make for a more readable >>>> solution, but I can not seem to get the syntax right; if we already >>>> fully support it at all ;-) >>>> >>>> I hope I did not get you all wrong, feel free to ask for more help! >>>> ;-) >>>> >>>> Best >>>> Michael >>>> >>>> [1] >>>> https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function >>>> -invocation >>>> >>>>> Am 28.08.2017 um 16:42 schrieb r.stapper at lijbrandt.nl: >>>>> >>>>> Hi, >>>>> >>>>> I want to use the apply function within an updating webfunction, >>>>> see[1] How can this be done? >>>>> >>>>> TIA, >>>>> >>>>> Rob Stapper >>>>> >>>>> [1] >>>>> declare >>>>> %rest:path("/cFactBank/dbCreate") >>>>> %rest:PUT("{$dataRec}") >>>>> %input:json("format=map") >>>>> >>>>> %updating >>>>> function _:cFactBank.dbCreate >>>>> ( $dataRec as array(*) >>>>> ) >>>>> { >>>>> apply( db:create#1 >>>>> , $dataRec >>>>> ) >>>>> } ; >> >> >
Written for BaseX 8.6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery