Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC:

JSON Parser 23 Nov 2022 01:28 #24544

  • jonhn
  • jonhn's Avatar
  • Topic Author


  • Posts: 72
  • I would like to export from a DBF to JSON, and also re-import from a JSON file.
    There was some discussion here: www.xsharp.eu/forum/german/3157-vo-und-restapi which provides a lot of information, and there is a VO version (or maybe it is Vulcan) in the JSONparser.zip.

    I have loaded it into VO and was intending to bring it to X# via the VOXporter but there are a couple of missing functions/methods.
    Has anyone already fixed this up and brought into X# that they would share (or sell?)?

    It seems that it is very close to what I am looking for.
    The missing methods are:
    fFileRead
    fFileWrite
    MsgInternalError
    AScanSymbol
    SafeCreateInstance
    RemoveZeroDecimals

    Thanks! Jonathan

    Please Log in or Create an account to join the conversation.

    JSON Parser 23 Nov 2022 08:12 #24545

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • If you want to use JSON in X# I recommand Newtonsoft . Very powerful and widely used.

    Stefan

    Please Log in or Create an account to join the conversation.

    JSON Parser 24 Nov 2022 01:10 #24552

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Thank you Stefan, it looks perfect.
    A question: To use it in my X# application which I edit in the XIDE, I first need to import it to VS, right?

    1) create new solution (Vo MDI/X# flavor) in VS
    2) use Nuget manager to download and install the package...
    3) ?
    Can I then copy the code over to XIDE, along with the Newtonsoft.JSON DLLs and use it there? Or is there more to be done?

    I'm unsure how to massage it into the XIDE if anyone has a hint, or can confirm the steps above are about right that'd be very helpful.
    Thanks! Jonathan

    Please Log in or Create an account to join the conversation.

    JSON Parser 24 Nov 2022 08:35 #24553

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • Hi Jonathan
    you can download directly from github ( link ).
    After unpacking and referencing the correct framework version (e.g. net45) you can use it in X#.
    Stefan

    If you need something from nuget you do not have to use VS. I prefer to download the correct version from nuget.org directly. You get a nupkg file. Rename this to zip, unpack and extract the dll you need.

    Please Log in or Create an account to join the conversation.

    JSON Parser 24 Nov 2022 10:33 #24556

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Thanks Stefan, that's very helpful.
    OK, when I compile it X# requests System.Runtime reference, Ver 6.0.0., but there is only Ver 4.0.0. in the GAC.
    Maybe I'm calling the wrong functions. I'm declaring USING Newtonsoft.Json, and reading through this www.newtonsoft.com/json/help/html/readin...htm#TextReaderWriter

    Sorry to ask - (I am reading through the documentation slowly) but do you have a small sample of the syntax you could share, for example, to read self:oDCMLE1:textvalue, translate it to JSON and display it in self:oDCMLE2:textvalue?
    Thanks, Jon

    Please Log in or Create an account to join the conversation.

    JSON Parser 24 Nov 2022 13:14 #24558

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • I am using LINQ to JSON.
    newtonsoft.com/json/help/html/LINQtoJSON.htm

    You can create JSON file from every object. All its public properties will be inserted. You can use Attributes für converting, renaming or ignoring values. You can also create the JSON object manually (look at the samples).
    For parsing the SelectToken method is very powerful. You can extract very easily the values you need.

    from the samples converted to X#
    VAR o := Newtonsoft.Json.Linq.JObject.Parse("{'Stores': ['Lambton Quay','Willis Street'],'Manufacturers': [{'Name': 'Acme Co','Products': [{'Name': 'Anvil','Price': 50}]},{'Name': 'Contoso','Products': [{'Name': 'Elbow Grease','Price': 99.95},{'Name': 'Headlight Fluid','Price': 4}]}]}")
    
    VAR name := (STRING)o:SelectToken("Manufacturers[0].Name")
    // Acme Co
    
    VAR productPrice := (Decimal)o:SelectToken("Manufacturers[0].Products[0].Price")
    // 50
    
    VAR productName := (STRING)o:SelectToken("Manufacturers[1].Products[0].Name")
    // Elbow Grease

    I don't know what is in your MLE1. But you can put it in JObject.Parse. If it fails the syntax is not correct. Inspect the exception to see where the error is. If syntax is OK, you can do: SELF:oDCMLE2:TextValue := o:ToString().

    Stefan

    Please Log in or Create an account to join the conversation.

    JSON Parser 07 Dec 2022 09:25 #24678

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Hi Stefan,

    I'm back to this creating JSON project. I'm clearly missing something simple here -
    The idea is to open a DBF and convert each record/field to JSON - it is kind of working but I'm not getting the structure or "" quite right.
    I'm getting a list of all the fields, but the records are not differentiated. Are you (or anyone) able to point out the missing link please?

    oServer := DbServer{"Schedule.dbf"}
    oServer:gotop()

    DO WHILE !oServer:Eof
    vText := Newtonsoft.Json.Linq.JValue.CreateString( "HIREINV : "+ Trim(oServer:Hireinv))
    aarray:Add( vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("DTSTART : "+Trim(oServer:DTSTART))
    aarray:Add(vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("DTEND : "+Trim(oServer:DTEND))
    aarray:Add(vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("ADDRESS : "+Trim(oServer:ADDRESS))
    aarray:Add(vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("CUSTOMER : "+Trim(oServer:CUSTOMER))
    aarray:Add(vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("PEOPLE : "+Str(oServer:PEOPLE,5,2))
    aarray:Add(vText)
    vText := Newtonsoft.Json.Linq.JValue.CreateString("HOURS : "+Str(oServer:HOURS,5,2))
    aarray:Add(vText)

    IF oServer:FLEXIBLE
    vText := Newtonsoft.Json.Linq.JValue.CreateString("FLEXIBLE : "+"TRUE")
    ELSE
    vText := Newtonsoft.Json.Linq.JValue.CreateString("FLEXIBLE : "+"FALSE")
    ENDIF

    aarray:Add(vText)
    oServer:Skip()
    ENDDO

    The result is below. The curly brackets are not around the records, and also the " " are not in the right places - there should be a pair around each : in each string.
    [
    "HIREINV : 143273",
    "DTSTART : 2022-12-07T09:00:00",
    "DTEND : 2022-12-07T11:00:00",
    "ADDRESS : Newmarket",
    "CUSTOMER : ARC BRANCH",
    "PEOPLE : 2.00",
    "HOURS : 1.16",
    "FLEXIBLE : FALSE",
    "HIREINV : 143407",
    "DTSTART : 2022-12-07T15:00:00",
    "DTEND : 2022-12-07T16:00:00",
    "ADDRESS : 43 Maskell Street- St Heliers",
    "CUSTOMER : ST HELIERS KIND",
    "PEOPLE : 1.00",
    "HOURS : 0.50",
    "FLEXIBLE : FALSE",
    "HIREINV : 143549",
    "DTSTART : 2022-12-08T08:00:00",
    "DTEND : 2022-12-08T09:00:00",
    "ADDRESS : Hyundai; Marine Sports Centre; 8/10 Tamaki Drive;",
    "CUSTOMER : UniServices @ HMSC",
    "PEOPLE : 1.00",
    "HOURS : 1.00",
    "FLEXIBLE : FALSE"
    ]

    Thanks for any suggestions!

    Please Log in or Create an account to join the conversation.

    JSON Parser 07 Dec 2022 12:05 #24682

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • Hi John,

    not tested, but gives you an idea
    VAR jRecords := JArray{}
    DO WHILE !oServer:EOF
       VAR jRec := JObject{ OBJECT[]{2}{JProperty{"HIREINV", Trim(oServer:Hireinv)}, ;
                                                               JProperty{"DTSTART ", Trim(oServer:DTSTART)},;
                                                                /* add your fields, an set the number of items in the initializer */
                                                                } }
       /* you can also add items here, jRec:Add( JProperty{"name", <SOME VALUE>} ) */
       jRecords:Add(jRec)
       oServer:Skip(1)
    END DO
    VAR txt := jRecords:ToString()

    Stefan

    Please Log in or Create an account to join the conversation.

    JSON Parser 08 Dec 2022 02:06 #24694

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Yes, that works perfectly! Like magic really. :)
    Thank you.

    Please Log in or Create an account to join the conversation.

    JSON Parser 08 Dec 2022 10:56 #24702

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Hi again... With your suggestion I can save the JSON file to a file, and now I want to read it back in after a 3rd party has edited it.

    To decode the JSON file it must be the same process in reverse?
    I read the file into a string - (in this case I put it in the SELF:oDCMLE1:textvalue) - this works
    Parse it into a JSON array - aSchedule := JArray.Parse(SELF:oDCMLE1:TextValue) - this works
    change it to a string json := aSchedule:ToString() -this works

    I'm stuck here - The below doesn't work - but I want to have an object I can loop through, extracting the fields of each record and then save to the dbf. I'm barking up the wrong tree.

    Do I use the JArray and extract the objects, or a string?

    Is it this kind of thing? (this does not work as I have it)
    VAR o := Newtonsoft.Json.Linq.JValue.Parse(json)
    VAR Invoice := (STRING)o:SelectToken("HIREINV[0]")
    VAR START := (STRING)o:SelectToken("DTSTART[0]")

    Or is it like the export example you provided, but in reverse?
    Thank you.

    Please Log in or Create an account to join the conversation.

    JSON Parser 08 Dec 2022 13:54 #24704

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • Hi,

    if your json is an object ( {..} ) then

    VAR Invoice := (STRING)o:SelectToken("HIREINV")

    www.newtonsoft.com/json/help/html/SelectToken.htm

    Stefan

    Please Log in or Create an account to join the conversation.

    JSON Parser 09 Dec 2022 07:43 #24710

    • Sherlock
    • Sherlock's Avatar


  • Posts: 51
  • I wrote a JSON to import to DBSERVER,, way back.. hope this helps someone

    METHOD AppendJSON( oFSSource ) CLASS DBServer

    LOCAL lRetCode := FALSE AS LOGIC
    LOCAL cSource AS STRING
    LOCAL cPath AS STRING
    LOCAL oError AS USUAL
    LOCAL dwCurrentWorkArea AS DWORD
    LOCAL jp AS JsonParser
    LOCAL ja AS JsonArray
    LOCAL jo AS JsonObject
    LOCAL aDBStruct := {} AS ARRAY
    LOCAL aAllkeys := {} AS ARRAY
    LOCAL xx, yy, nPos AS DWORD
    LOCAL uValue AS USUAL

    #IFDEF __DEBUG__
    DBFDebug("Entering "+__ENTITY__)
    #ENDIF
    //
    SELF:lErrorFlag := FALSE
    //
    BEGIN SEQUENCE
    VODBSelect( wWorkArea, @dwCurrentWorkArea )
    IF SELF:Notify( NOTIFYINTENTTOMOVE )
    IF IsInstanceOfUsual( oFSSource, #FileSpec )
    cSource := oFSSource:FullPath
    ELSE
    cSource := oFSSource
    IF At2( "\", cSource ) == 0
    cPath := SELF:oFileSpec:FullPath
    cSource := SubStr3( cPath, 1, RAt2( "\", cPath ) ) + cSource
    ENDIF
    ENDIF
    //
    aDBStruct := SELF:DbStruct // Get structure array from DBF
    //
    jp := JsonParser{}
    IF jp:LoadFromFile( cPath+cSource ) // Read the JSON data, import to DBF
    //
    ja := jp:RootJson:ValAsArray // Get Root JSON array of records
    // JSON data types to check... now match to DBF data types
    // JsonType_String := 0 / JsonType_LongInt := 1 / JsonType_Real8 := 2 / JsonType_Float := 2
    // JsonType_Logic := 3 / JsonType_Null := 4 / JsonType_Object := 5 / JsonType_Array := 6
    //
    FOR xx := 1 TO ja:Size // 1 to All Json array records...
    jo := ja:GetJsonObject(xx) // Jo will be a Record, ie. "Prop_code TO "B_zzclean2" jo:Size = 42
    //
    IF SELF:APpend() // Append to the DBF the data from JSON data
    //
    aAllkeys := jo:AllKeys // All the keys is the FIELD names.
    //
    FOR yy := 1 TO ALen(aAllkeys)
    // ? aAllkeys[yy] , jo:GetJsonValue(aAllkeys[yy]):JsonType // String = 0 / Numeric = 1,2 / Logic = 3
    nPos := AScan(aDBStruct, {|a| a[DBS_NAME] == aAllkeys[yy]})
    IF nPos > 0
    //
    DO CASE
    CASE aDBStruct[nPos][ DBS_TYPE ] = "C" ; uValue := jo:GetString(aAllkeys[yy]) // DBF needs "C"har string format
    CASE aDBStruct[nPos][ DBS_TYPE ] = "D" ; uValue := SToD(StrTran(jo:GetString(aAllkeys[yy]),[-])) // DBF needs "D"ate YYYY-DD-MM
    CASE aDBStruct[nPos][ DBS_TYPE ] = "N" ; uValue := jo:GetFloat(aAllkeys[yy]) // DBF need "N"umeric could be float or Int style
    uValue := Round( uValue, aDBStruct[nPos][ DBS_DEC ]) // Take Json value and trim to DBF field length [ie. 123.00 Round( xxx, 0) = 123
    IF SLen(AsString(uValue)) > aDBStruct[nPos][ DBS_LEN ] // resolve 2.0 v 2 [ int ] // Length of "new" Json data, verse field length
    uValue := 0 // If it will not fit, zero it.. else a crash.
    ENDIF
    CASE aDBStruct[nPos][ DBS_TYPE ] = "L" ; uValue := jo:Getlogic(aAllkeys[yy]) // DBF needs "L"ogic Json data as TRUE or FALSE
    CASE aDBStruct[nPos][ DBS_TYPE ] = "M" ; uValue := jo:GetString(aAllkeys[yy]) // DBF needs "M"emo as string, we do not allow Arrays, even though memo allows
    ENDCASE
    //
    SELF:FIELDPUT(aAllkeys[yy], uValue ) // Have FIELD NAME and value... write it.
    ENDIF
    //
    NEXT
    ENDIF
    NEXT
    SELF:Commit() // Commit the full record the say 42 fields..
    SELF:Unlock() // Unlock that record, the APPEND locked it.
    //
    lRetCode := TRUE
    ENDIF
    IF lRetCode
    lRetCode := SELF:__ProcessConcurrency( TRUE )
    ENDIF
    SELF:Notify( NOTIFYFILECHANGE )
    siSelectionStatus := DBSELECTIONNULL
    ELSE
    lRetCode := FALSE
    SELF:__SetStatusHL ( #AppendSDF, __CavoStr( __CAVOSTR_DBFCLASS_INTENTTOMOVE_CAPTION ), ;
    __CavoStr( __CAVOSTR_DBFCLASS_INTENTTOMOVE ) )
    ENDIF
    __DBSSetSelect( dwCurrentWorkArea ) //SE-060527
    //
    RECOVER USING oError
    oHLStatus := SELF:__GenerateStatusHL( oError )
    oErrorInfo := oError
    //
    SELF:__ProcessConcurrency( FALSE )
    //
    __DBSSetSelect( dwCurrentWorkArea ) //SE-060527
    lRetCode := FALSE
    //
    END SEQUENCE
    //
    #IFDEF __DEBUG__
    DBFDebug("Leaving "+__ENTITY__, AsString(lRetCode))
    #ENDIF
    //
    RETURN lRetCode
    Phil McGuinness

    Please Log in or Create an account to join the conversation.

    JSON Parser 11 Dec 2022 04:26 #24719

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • I still can't get this - sorry to ask again. I end up going in circles trying different possibilities and doubling back on myself.
    My JSON string is below, and for testing I load it into an MLE text field and then try parsing it in different ways.

    Method 1)
    VAR o:= JArray.Parse(SELF:oDCMLE1:TextValue)
    VAR Invoice := (STRING)o:SelectToken("HIREINV")
    *** Invoice is empty.

    Method 2
    VAR o := Newtonsoft.Json.Linq.JARRAY.Parse(SELF:oDCMLE1:TextValue)
    VAR Invoice := (STRING)o:SelectToken("HIREINV")
    *** Invoice is empty.

    (Method 3~70 result in a RT error or won't compile, haha)

    Is my JSON string valid for this approach?
    Do you think the object is actually loaded correctly by either of the above, and the field is not being located?
    Or is my "object" invalid and nothing is loaded?
    I think probably it is valid, but maybe I'm not moving to the first record - so then I start to doubt that my JSON object is valid (but it checks out online)

    If anyone can point out what I've got wrong here that would be great!
    The other question is: If I do eventually point to the first record and find the field, how do you skip to the next record?

    Here is the JSON STRING I'm testing with:
    [{
    "HIREINV ": "143180",
    "DTSTART ": "2022-12-14T09:00:00",
    "DTEND ": "2022-12-14T12:00:00",
    "DELPU ": "DEL",
    "CUSTOMER ": "NZMARINE",
    "PEOPLE ": " 4.00",
    "HOURS ": " 3.00",
    "FLEXIBLE": "FALSE"
    },
    {
    "HIREINV ": "143584",
    "DTSTART ": "2022-12-14T16:00:00",
    "DTEND ": "2022-12-14T18:00:00",
    "DELPU ": "DEL",
    "CUSTOMER ": "SEKTOR",
    "PEOPLE ": " 3.00",
    "HOURS ": " 2.00",
    "FLEXIBLE": "FALSE"
    },
    {
    "HIREINV ": "143799",
    "DTSTART ": "2022-12-14T09:00:00",
    "DTEND ": "2022-12-14T12:00:00",
    "DELPU ": "DEL",
    "CUSTOMER ": "NZ MARINE",
    "PEOPLE ": " 4.00",
    "HOURS ": " 3.00",
    "FLEXIBLE": "FALSE"
    },
    {
    "HIREINV ": "143893",
    "DTSTART ": "2022-12-14T06:00:00",
    "DTEND ": "2022-12-14T06:00:00",
    "DELPU ": "DEL",
    "CUSTOMER ": "BLADON",
    "PEOPLE ": " 0.00",
    "HOURS ": " 0.00",
    "FLEXIBLE": "FALSE"
    },
    {
    "HIREINV ": "143930",
    "DTSTART ": "2022-12-13T09:00:00",
    "DTEND ": "2022-12-13T10:00:00",
    "DELPU ": "PIK",
    "CUSTOMER ": "ONSLOW",
    "PEOPLE ": " 1.00",
    "HOURS ": " 1.00",
    "FLEXIBLE": "FALSE"
    },
    {
    "HIREINV ": "143584",
    "DTSTART ": "2022-12-14T08:00:00",
    "DTEND ": "2022-12-14T09:00:00",
    "DELPU ": "TECH",
    "CUSTOMER ": "Christmas Party",
    "PEOPLE ": " 1.00",
    "HOURS ": " 1.00",
    "FLEXIBLE": "FALSE"
    }
    ]

    Please Log in or Create an account to join the conversation.

    JSON Parser 11 Dec 2022 13:54 #24721

    • SHirsch
    • SHirsch's Avatar


  • Posts: 266
  • everything OK with you json. The access is not correct. See the following sample:
    FUNCTION JsonTest() AS VOID
    VAR jsonTxt := "[{'HIREINV':'143180','DTSTART':'2022-12-14T09:00:00','DTEND':'2022-12-14T12:00:00','DELPU':'DEL','CUSTOMER':'NZMARINE','PEOPLE':' 4.00','HOURS':' 3.00','FLEXIBLE':'FALSE'},{'HIREINV':'143584','DTSTART':'2022-12-14T16:00:00','DTEND':'2022-12-14T18:00:00','DELPU':'DEL','CUSTOMER':'SEKTOR','PEOPLE':' 3.00','HOURS':' 2.00','FLEXIBLE':'FALSE'},{'HIREINV':'143799','DTSTART':'2022-12-14T09:00:00','DTEND':'2022-12-14T12:00:00','DELPU':'DEL','CUSTOMER':'NZ MARINE','PEOPLE':' 4.00','HOURS':' 3.00','FLEXIBLE':'FALSE'},{'HIREINV':'143893','DTSTART':'2022-12-14T06:00:00','DTEND':'2022-12-14T06:00:00','DELPU':'DEL','CUSTOMER':'BLADON','PEOPLE':' 0.00','HOURS':' 0.00','FLEXIBLE':'FALSE'},{'HIREINV':'143930','DTSTART':'2022-12-13T09:00:00','DTEND':'2022-12-13T10:00:00','DELPU':'PIK','CUSTOMER':'ONSLOW','PEOPLE':' 1.00','HOURS':' 1.00','FLEXIBLE':'FALSE'},{'HIREINV':'143584','DTSTART':'2022-12-14T08:00:00','DTEND':'2022-12-14T09:00:00','DELPU':'TECH','CUSTOMER':'Christmas Party','PEOPLE':' 1.00','HOURS':' 1.00','FLEXIBLE':'FALSE'}]"
    
    VAR jArr := NewtonSoft.Json.Linq.JArray.Parse(jsonTxt)
    
    //go over each array item
    FOREACH jObj AS Newtonsoft.Json.Linq.JObject IN jArr  
        //jObj contains now one Item
        VAR hireinv := (STRING)jObj:SelectToken("HIREINV")
        Console.WriteLine(hireinv)
    NEXT
    
    //you could get a special item from the array
    VAR secondsHireinv := (STRING) jArr:SelectToken("[1].HIREINV")
    Console.WriteLine("direct access: "+secondsHireinv)  
    
    Console.WriteLine("now with a root object")
    VAR jsonTxt2 := "{'data':[{'HIREINV':'143180','DTSTART':'2022-12-14T09:00:00','DTEND':'2022-12-14T12:00:00','DELPU':'DEL','CUSTOMER':'NZMARINE','PEOPLE':' 4.00','HOURS':' 3.00','FLEXIBLE':'FALSE'},{'HIREINV':'143584','DTSTART':'2022-12-14T16:00:00','DTEND':'2022-12-14T18:00:00','DELPU':'DEL','CUSTOMER':'SEKTOR','PEOPLE':' 3.00','HOURS':' 2.00','FLEXIBLE':'FALSE'},{'HIREINV':'143799','DTSTART':'2022-12-14T09:00:00','DTEND':'2022-12-14T12:00:00','DELPU':'DEL','CUSTOMER':'NZ MARINE','PEOPLE':' 4.00','HOURS':' 3.00','FLEXIBLE':'FALSE'},{'HIREINV':'143893','DTSTART':'2022-12-14T06:00:00','DTEND':'2022-12-14T06:00:00','DELPU':'DEL','CUSTOMER':'BLADON','PEOPLE':' 0.00','HOURS':' 0.00','FLEXIBLE':'FALSE'},{'HIREINV':'143930','DTSTART':'2022-12-13T09:00:00','DTEND':'2022-12-13T10:00:00','DELPU':'PIK','CUSTOMER':'ONSLOW','PEOPLE':' 1.00','HOURS':' 1.00','FLEXIBLE':'FALSE'},{'HIREINV':'143584','DTSTART':'2022-12-14T08:00:00','DTEND':'2022-12-14T09:00:00','DELPU':'TECH','CUSTOMER':'Christmas Party','PEOPLE':' 1.00','HOURS':' 1.00','FLEXIBLE':'FALSE'}]}"
    
    VAR jRootObj := NewtonSoft.Json.Linq.JObject.Parse(jsonTxt2)
    
    //go over each array item
    FOREACH jObj AS Newtonsoft.Json.Linq.JObject IN (NewtonSoft.Json.Linq.JArray)jRootObj:SelectToken("data")  
        //jObj contains now one Item
        VAR hireinv := (STRING)jObj:SelectToken("HIREINV")
        Console.WriteLine(hireinv)
    NEXT
    
    //you could get a special item from the array
    secondsHireinv := (STRING) jRootObj:SelectToken("data[1].HIREINV")
    Console.WriteLine("direct access: "+secondsHireinv)  
    RETURN

    Stefan

    Please Log in or Create an account to join the conversation.

    JSON Parser 12 Dec 2022 09:26 #24725

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Stefan, Thank you for taking the trouble with all the examples- and yes, that is everything I was looking for (and some more) and it works as required.
    One thing - my string was not right, and this was causing some problems. The JSON was valid, but there were additional spaces in my field names (before the ") and that was also critical to the parsing succeeding.
    Thank you. Jonathan

    Please Log in or Create an account to join the conversation.

    JSON Parser 12 Dec 2022 20:03 #24742

    • Meinhard
    • Meinhard's Avatar


  • Posts: 75
  • Hi Jonathan,
    need to add my 2 cents here too :)

    Let's assume you put your data into a file (easier then to put it into a string in code ) named TestData.json. You need to delete the additional space in the property names first!.Then define a class like this:

    PUBLIC CLASS JsonRow
    CONSTRUCTOR()
    PUBLIC PROPERTY HIREINV AS STRING GET SET
    PUBLIC PROPERTY DTSTART AS STRING GET SET
    PUBLIC PROPERTY DTEND AS STRING GET SET
    PUBLIC PROPERTY DELPU AS STRING GET SET
    PUBLIC PROPERTY CUSTOMER AS STRING GET SET
    PUBLIC PROPERTY PEOPLE AS STRING GET SET
    PUBLIC PROPERTY HOURS AS STRING GET SET
    PUBLIC PROPERTY FLEXIBLE AS STRING GET SET
    END CLASS

    Now it is easy to deserialize the data into alist of JsonRows:

    USING System.Text
    USING System.IO
    using System.Text.Json
    using System.Text.Json.Serialization

    FUNCTION Start() AS VOID STRICT
    ?"Hello World!"
    VAR jsonData := File.ReadAllText("TestData.json")
    VAR listOfRows := JsonSerializer.Deserialize<List<JsonRow>>(jsonData)
    FOREACH var row in listOfRows
    ? row:CUSTOMER
    NEXT
    WAIT
    RETURN

    Instead of NewtonSoft I am using the System.Text.Json package here.If you don't likethe list, you can deserialize to an typed array as well :
    var arrayOfJsonRow:=JsonSerializer.Deserialize<JsonRow[]>(jsonData)

    Regards
    Meinhard

    Please Log in or Create an account to join the conversation.

    JSON Parser 12 Dec 2022 21:17 #24743

    • jonhn
    • jonhn's Avatar
    • Topic Author


  • Posts: 72
  • Brilliant, thank you! In my case with a very simple requirement this is a good option so I'll experiment with this too.
    So many ways to skin a cat...
    By the way - where is this function from File.ReadAllText - I see a lot of core File functions in X#, but not this one... a replacement for Memoread()?
    BR, Jonathan

    Please Log in or Create an account to join the conversation.

    JSON Parser 12 Dec 2022 22:28 #24744

    • ic2
    • ic2's Avatar


  • Posts: 1574
  • Please Log in or Create an account to join the conversation.

    • Page:
    • 1