[basex-talk] JSON output in PHP client

2014-07-11 Thread Paul Swennenhuis
I've been playing a bit with BaseX the last couple of days - and very 
excited about the product while doing so - but now I am having problems 
outputting JSON from a PHP script.


I have this XQuery:

declare option output:method json;
declare option output:json format=jsonml;
json type=object
{
for $user in 
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
return
testResults
  testId{$user/test/_id}/testId
  grade{$user/user_info/user_grade}/grade
  /testResults
}
/json

In the BaseX GUI this yields:

[json, {type:object},
  [testResults,
[testId,
  [_id,
Bio-1]],
[grade,
  [user_grade,
7]]],
  [testResults,
[testId,
  [_id,
Bio-2]],
[grade,
  [user_grade,
1

Which is what I expected after reading about the JSONML format. (Not too 
happy with that format, but that's another story).


Running exactly the same XQuery form within a PHP script however yields 
this:


json  type=object
  testResults
testId
  _idBio-1/_id
/testId
grade
  user_grade7/user_grade
/grade
  /testResults
  testResults
testId
  _idBio-2/_id
/testId
grade
  user_grade1/user_grade
/grade
  /testResults
/json


(script is attached; note that the $ signs have been escaped there so 
that PHP will not try to evaluate them)


In other words, the result is being output as XML with an enclosing 
json root tag, not as JSON.


What is happening here? And how can I have BaseX return JSON from PHP?

Paul Swennenhuis




?php
/*
 * This example shows how queries can be executed in an iterative manner.
 * Documentation: http://basex.org/api
 *
 * (C) BaseX Team 2005-11, BSD License
 */
include(BaseXClient.php);


 
try {
  // create session
  $session = new Session(localhost, 1984, admin, a33445);
   
  try {
// create query instance
  
// make sure to escape $ signs!
 $input = XQ
declare option output:json format=jsonml;
json type=object
{
for \$user in 
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
return

testResult
  testId{\$user/test/_id}/testId
  grade{\$user/user_info/user_grade}/grade
  /testResult
}
/json

 
XQ;
//print $input;

$query = $session-query($input);
 
// bind variable
//$query-bind($name, number);
 
 
print $query-execute().\n;
   
 
// close query instance
$query-close();
 
  } catch (Exception $e) {
// print exception
print $e-getMessage();
  }
 
  // close session
  $session-close();
 
} catch (Exception $e) {
  // print exception
  print $e-getMessage();
}
?

Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Christian Grün
Hi Paul,

 Which is what I expected after reading about the JSONML format. (Not too
 happy with that format, but that's another story).

I agree; JSONML is a quasi-standard we have adopted, which is mainly useful
for converting arbitrary XML to JSON. If you can decide how your XML format
looks like, I would recommend the standard conversion format:

declare option output:method json;

  json type=array objects='_'{
for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
return
  testResults
testId{$user/test/_id}/testId
grade{$user/user_info/user_grade}/grade
/testResults
  }/json


 Running exactly the same XQuery form within a PHP script however yields
 this:

The query results are currently sent to all clients in their standard
format (i.e., ignoring all serialization parameters). That's why you'll
need to convert your JSON within XQuery:

  json:serialize(
json type=array objects='_'{
  ...
}/json
  )

If I remember what was the reason for that design decision, I'll give you
an update soon..

Hope this helps,
Christian


Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Paul Swennenhuis

Hi Christian,

Thanks for the quick answer.
Unfortunately your proposed solution (json:serialize) does not work in 
this case; BaseX returns a BXJS0002 error:

JSON serializer: found, _ expected.

The modified query reads:

json:serialize(
json type=array objects='_'{
for \$user in 
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
return
testResult
  testId{\$user/test/_id}/testId
  grade{\$user/user_info/user_grade}/grade
  /testResult
}
/json
)

Paul


Hi Paul,

 Which is what I expected after reading about the JSONML format. (Not too
 happy with that format, but that's another story).

I agree; JSONML is a quasi-standard we have adopted, which is mainly 
useful for converting arbitrary XML to JSON. If you can decide how 
your XML format looks like, I would recommend the standard conversion 
format:


declare option output:method json;

  json type=array objects='_'{
for $user in 
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]

return
  testResults
testId{$user/test/_id}/testId
grade{$user/user_info/user_grade}/grade
/testResults
  }/json


 Running exactly the same XQuery form within a PHP script however yields
 this:

The query results are currently sent to all clients in their standard 
format (i.e., ignoring all serialization parameters). That's why 
you'll need to convert your JSON within XQuery:


  json:serialize(
json type=array objects='_'{
  ...
}/json
  )

If I remember what was the reason for that design decision, I'll give 
you an update soon..


Hope this helps,
Christian





Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Christian Grün
I should have run your query before sending you an answer. The
following query should work:

json:serialize(
  json type=array objects='_'{
  for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
  return
  _
testId{$user/test/_id}/testId
grade{$user/user_info/user_grade}/grade
  /_
  }/json
)



 Which is what I expected after reading about the JSONML format. (Not too
 happy with that format, but that's another story).

 I agree; JSONML is a quasi-standard we have adopted, which is mainly useful
 for converting arbitrary XML to JSON. If you can decide how your XML format
 looks like, I would recommend the standard conversion format:

 declare option output:method json;

   json type=array objects='_'{
 for $user in
 collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
 return
   testResults
 testId{$user/test/_id}/testId
 grade{$user/user_info/user_grade}/grade
 /testResults
   }/json


  Running exactly the same XQuery form within a PHP script however yields
 this:

 The query results are currently sent to all clients in their standard format
 (i.e., ignoring all serialization parameters). That's why you'll need to
 convert your JSON within XQuery:

   json:serialize(
 json type=array objects='_'{
   ...
 }/json
   )

 If I remember what was the reason for that design decision, I'll give you an
 update soon..

 Hope this helps,
 Christian




Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Paul Swennenhuis

Still no luck:
JSON serializer: testId is typed as string and cannot be nested

I think I am going to move the JSON conversion to within PHP or 
Javascript, and keep the XQueries clean and readable.


Paul

json:serialize(
   json type=array objects='_'{
   for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
   return
   _
 testId{$user/test/_id}/testId
 grade{$user/user_info/user_grade}/grade
   /_
   }/json
)




Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Dirk Kirsten
Hi Paul,

no need to despair ;)

The default JSON converter is the direct one (which would require
testId/ to be declared an object), not JsonML. If you you want to use
JsonML you can do so by using

json:serialize(
   json type=array objects='_'{
   for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
   return
   _
 testId{$user/test/_id}/testId
 grade{$user/user_info/user_grade}/grade
   /_
   }/json,
  map { 'format': 'jsonml' }
)

For some more information you can take a look at
https://docs.basex.org/wiki/JSON_Module

Cheers,
Dirk

On 11/07/14 12:13, Paul Swennenhuis wrote:
 Still no luck:
 JSON serializer: testId is typed as string and cannot be nested
 
 I think I am going to move the JSON conversion to within PHP or
 Javascript, and keep the XQueries clean and readable.
 
 Paul
 json:serialize(
json type=array objects='_'{
for $user in
 collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]

return
_
  testId{$user/test/_id}/testId
  grade{$user/user_info/user_grade}/grade
/_
}/json
 )
 

-- 
Dirk Kirsten, BaseX GmbH, http://basex.org
|-- Firmensitz: Blarerstrasse 56, 78462 Konstanz
|-- Registergericht Freiburg, HRB: 708285, Geschäftsführer:
|   Dr. Christian Grün, Dr. Alexander Holupirek, Michael Seiferle
`-- Phone: 0049 7531 28 28 676, Fax: 0049 7531 20 05 22


Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Paul Swennenhuis
Ah, yes, that did the trick. I read about the options but had forgotten 
about it.

Thanks.
I will run some performance tests to decide for json:serialize or PHP 
internal conversion which might be considerably slower.


Paul

json:serialize(
json type=array objects='_'{
for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
return
_
  testId{$user/test/_id}/testId
  grade{$user/user_info/user_grade}/grade
/_
}/json,
   map { 'format': 'jsonml' }
)




Re: [basex-talk] JSON output in PHP client

2014-07-11 Thread Christian Grün
Hi Paul, and thanks Dirk.

One last note: If you plan to stick with JsonML, you can serialize
arbitrary XML data, such as..

json:serialize(
   xml{
   for $user in
collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
   return
   result
 testId{$user/test/_id}/testId
 grade{$user/user_info/user_grade}/grade
   /result
   }/xml,
  map { 'format': 'jsonml' }
)

C.


On Fri, Jul 11, 2014 at 12:48 PM, Paul Swennenhuis p...@swennenhuis.nl wrote:
 Ah, yes, that did the trick. I read about the options but had forgotten
 about it.
 Thanks.
 I will run some performance tests to decide for json:serialize or PHP
 internal conversion which might be considerably slower.

 Paul

 json:serialize(
 json type=array objects='_'{
 for $user in
 collection(saveresult)//user[_id=1f2cda8f-a18a-44ba-8d17-73626d472306]
 return
 _
   testId{$user/test/_id}/testId
   grade{$user/user_info/user_grade}/grade
 /_
 }/json,
map { 'format': 'jsonml' }
 )