WRITE-JSON from DataSet, without JsonArray - Forum - OpenEdge Development - Progress Community

WRITE-JSON from DataSet, without JsonArray

 Forum

WRITE-JSON from DataSet, without JsonArray

This question has suggested answer(s)

I'm currently attempting to output a DataSet to a JsonObject, to match a given API. So, this is my example code:

DEFINE VARIABLE lh_Relation AS HANDLE NO-UNDO.
DEFINE VARIABLE lh_DataSet AS HANDLE NO-UNDO.
DEFINE VARIABLE lobj_JsonObject AS JsonObject NO-UNDO.
DEFINE VARIABLE llc_JsonOutput AS LONGCHAR NO-UNDO.

lobj_JsonObject = NEW JsonObject().

DEFINE TEMP-TABLE tt_Object SERIALIZE-NAME "data"
    FIELD lc_Type AS CHARACTER SERIALIZE-NAME "type"
    FIELD lde_ID AS DECIMAL SERIALIZE-NAME "id" .

DEFINE TEMP-TABLE tt_Attributes SERIALIZE-NAME "attributes"
   FIELD lde_ObjectID AS DECIMAL
   FIELD lc_Name AS CHARACTER SERIALIZE-NAME "name".

CREATE DATASET lh_DataSet.
lh_DataSet:NAME = "".
lh_DataSet:SET-BUFFERS(BUFFER tt_Object:HANDLE,
                                             BUFFER tt_Attributes:HANDLE).

lh_Relation = lh_DataSet:ADD-RELATION(BUFFER tt_Object:HANDLE,
                                                                     BUFFER tt_Attributes:HANDLE,
                                                                     "lde_ID,lde_ObjectID",
                                                                     FALSE, TRUE, TRUE, FALSE, TRUE).
CREATE tt_Object.
ASSIGN tt_Object.lc_Type = "driver"
               tt_Object.lde_ID = 1.

CREATE tt_Attributes.
ASSIGN tt_Attributes.lde_ObjectID = 1
               tt_Attributes.lc_Name = "Steve".

lh_DataSet:WRITE-JSON ("FILE", "C:\temp\jsonOutput.txt", TRUE, "UTF-8", FALSE, TRUE).

Which produces the following output:

{
  "data": [
    {
      "type": "driver",
      "id": 1.0,
      "attributes": [
        {
          "name": "Steve"
        }
      ]
    }
  ]
}

I need to have it look like this:

{
  "data":
    {
      "type": "driver",
      "id": 1.0,
      "attributes": 
        {
          "name": "Steve"
        }
    }
}

The difference being that the temp-tables in the actual output become JsonArrays, before being added to the overall JsonObject - that isn't what I need/want. I can create the desired output by simply doing it manually - which for this example isn't too difficult, but the datasets that I will be working with are much more complex than this.

Is it possible to do what I need to do, without resorting to overly complex manual processing? Thanks in advance!

EDIT: I should also point out that I am using OE11.5.

All Replies
  • Not that I can think of.

    If you can guarantee that each TT will only have one record, it shouldn't be too hard to create something that'll do what you want dynamically so you only need to implement it once. 

    Tim

  • We had a similar issue and had to use SERIALIZE-ROW on the buffer object. The vendor we were exporting to wanted each record on a separate line...was not really valid JSON format.

  • Thanks for your replies both.

    Tim - Yes, I can guarantee that the TT will only have a single record. Which makes me feel that it shouldn't be a TT at all, but at the same time I can't figure out another way of storing the data. Short of storing it as a user defined object and then serializing that. Which again, seems like a lot of effort for something relatively simple.

    Roger - I don't think that would work in my case as I think I do need a dataset object to hold all of the various bits of data.

  • just use jsonobject instead of temp tables then you can arrange the data as you want

  • Manipulate resulting JsonObject.

    // lh_DataSet:WRITE-JSON ("FILE", "C:\temp\jsonOutput.txt", TRUE, "UTF-8", FALSE, TRUE).
    lh_DataSet:NAME = "x".
    lobj_JsonObject = NEW JsonObject().
    lobj_JsonObject:Read(lh_DataSet).
    
    lobj_JsonObject = lobj_JsonObject:GetJsonObject("x").
    lobj_JsonObject:Set("data", lobj_JsonObject:GetJsonArray("data"):GetJsonObject(1)).
    lobj_JsonObject:GetJsonObject("data"):Set("attributes", lobj_JsonObject:GetJsonObject("data"):GetJsonArray("attributes"):GetJsonObject(1)).
    lobj_JsonObject:WriteFile("C:\temp\jsonOutput.txt").
  • a suitable replacement for a temp-table with just one row would be a WORK-TABLE.

    Sadly, not all the features one might want to use are supported for these. while old, they would be just the thing for passing a record to functions, procedures, appserver, etc. as they have /much/ less overhead than temp-tables do.