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%E2%80%9C%3E <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ünter
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:
- Fetching data with fetch:text() calling a REST-API
- Transforming the data with json-to-xml, so I’ll get something like <array xmlns="http://www.w3.org/2005/xpath-functions%E2%80%9C%3E
<map> <string key=„word1“>gehen</string> ... </map> ... </array>
- In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json)
- 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']
It works. I’ll go with the second solution. Martin, thanks a lot!
Am 26.08.2017 um 12:26 schrieb Martin Honnen martin.honnen@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:
- Fetching data with fetch:text() calling a REST-API
- Transforming the data with json-to-xml, so I’ll get something like <array xmlns="http://www.w3.org/2005/xpath-functions%E2%80%9C%3E
<map> <string key=„word1“>gehen</string> ... </map> ... </array>
- In my xqm-file I have: let $json_xml := json-to-xml(my_fetched_json)
- 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']
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" } } ]
Günter Dunz-Wolff guenter.dunzwolff@gmail.com schrieb am 12:36 Samstag, 26.August 2017:
It works. I’ll go with the second solution. Martin, thanks a lot!
Am 26.08.2017 um 12:26 schrieb Martin Honnen martin.honnen@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:
- Fetching data with fetch:text() calling a REST-API
- Transforming the data with json-to-xml, so I’ll get something like
<array xmlns="http://www.w3.org/2005/xpath-functions%E2%80%9C%3E <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']
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" }
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
Liam R. E. Quin liam@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" }
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. [...]
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
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 ) } ;
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-invocat... https://www.w3.org/TR/xquery-update-30/#id-dynamic-updating-function-invocation
Am 28.08.2017 um 16:42 schrieb r.stapper@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 ) } ;
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-invocat...
Am 28.08.2017 um 16:42 schrieb r.stapper@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 ) } ;
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@lijbrandt.nl Ontvanger: Michael Seiferle ms@basex.org Kopie: BaseX basex-talk@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-invocat...
Am 28.08.2017 um 16:42 schrieb r.stapper@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 ) } ;
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@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@lijbrandt.nl Ontvanger: Michael Seiferle ms@basex.org Kopie: BaseX basex-talk@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-invocat...
Am 28.08.2017 um 16:42 schrieb r.stapper@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 ) } ;
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@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@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@lijbrandt.nl Ontvanger: Michael Seiferle ms@basex.org Kopie: BaseX basex-talk@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-invocat...
Am 28.08.2017 um 16:42 schrieb r.stapper@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 ) } ;
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@mailman.uni-konstanz.de [mailto:basex-talk-bounces@mailman.uni-konstanz.de] Namens Michael Seiferle Verzonden: dinsdag 29 augustus 2017 21:08 Aan: Marco Lettere CC: basex-talk@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@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@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@lijbrandt.nl Ontvanger: Michael Seiferle ms@basex.org Kopie: BaseX basex-talk@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@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 ) } ;
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
On Wed, Aug 30, 2017 at 7:37 AM, Rob Stapper r.stapper@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@mailman.uni-konstanz.de [mailto:basex-talk-bounces@mailman.uni-konstanz.de] Namens Michael Seiferle Verzonden: dinsdag 29 augustus 2017 21:08 Aan: Marco Lettere CC: basex-talk@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@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@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@lijbrandt.nl Ontvanger: Michael Seiferle ms@basex.org Kopie: BaseX basex-talk@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@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 ) } ;
basex-talk@mailman.uni-konstanz.de