Jump to content

A Non-Strict JSON UDF (JSMN)


Ward
 Share

Recommended Posts

3 hours ago, Jos said:

Please post an example of the data and what you like to retrieve so we understand what you are looking for. ;) 

Jos

{
    "result": {
        "items": [
            {
                "id": 8302563200,
                "name": 5712
            },
            {
                "id": 8407157165,
                "name": 5850
            },
            {
                "id": 8533482599,
                "name": 4560
            },
            {
                "id": 8590795041,
                "name": 5712
            },
            {
                "id": 8590795124,
                "name": 5712                    
            }
        ]
        
    }
}

For this example 'items' has 5 "containers" with names. I want result like a: found 5 names, 5712 - 3 times.

 

Link to comment
Share on other sites

The following shows a couple of ways to process an array of JSON objects.  The examples are over-simplified and do not contain any error checking.  You can add your own error checking, code optimization, and modification of the logic as needed.

#Include <json.au3> ;<== Change to your location

Global Const $JSON_DATA = _
                          '{' & _
                          '  "result":{' & _
                          '    "items":[' & _
                          '       {"name":"Becky",  "age":8},' & _
                          '       {"name":"Dave",   "age":6},' & _
                          '       {"name":"Ashley", "age":7}' & _
                          '    ]' & _
                          '  }' & _
                          '}'

for_in_next_example()
for_next_example()

Func for_in_next_example()
    ConsoleWrite("For...In...Next Example" & @CRLF)

    Local $oJson   = Json_Decode($JSON_DATA)            ;Decode JSON string
    Local $aoItems = Json_Get($oJson, ".result.items")  ;Get array of "Items" objects
    Local $sName
    Local $iAge

    For $oItem in $aoItems
        $sName   = Json_Get($oItem, ".name")
        $iAge    = Json_Get($oItem, ".age")
        ConsoleWrite($sName & " is " & $iAge & @CRLF)
    Next
    ConsoleWrite(@CRLF)
EndFunc

Func for_next_example()
    ConsoleWrite("For...Next Example" & @CRLF)

    Local $oJson      = Json_Decode($JSON_DATA)            ;Decode JSON string
    Local $aoItems    = Json_Get($oJson, ".result.items")  ;Get array of "Items" objects
    Local $iItemCount = UBound(Json_Get($oJson, ".result.items"))
    Local $sName
    Local $iAge


    For $i = 0 To $iItemCount - 1
        $sName = Json_Get($aoItems[$i], ".name")
        $iAge  = Json_Get($aoItems[$i], ".age")
        ConsoleWrite($sName & " is " & $iAge & @CRLF)
    Next

    ConsoleWrite(@CRLF)
EndFunc

Output:

For...In...Next Example
Becky is 8
Dave is 6
Ashley is 7

For...Next Example
Becky is 8
Dave is 6
Ashley is 7

 

Edited by TheXman
Link to comment
Share on other sites

25 minutes ago, TheXman said:

The following shows a couple of ways to process an array of JSON objects.  The examples are over-simplified and do not contain any error checking.  You can add your own error checking, code optimization, and modification of the logic as needed.

#Include <json.au3> ;<== Change to your location

Global Const $JSON_DATA = _
                          '{' & _
                          '  "result":{' & _
                          '    "items":[' & _
                          '       {"name":"Becky",  "age":8},' & _
                          '       {"name":"Dave",   "age":6},' & _
                          '       {"name":"Ashley", "age":7}' & _
                          '    ]' & _
                          '  }' & _
                          '}'

for_in_next_example()
for_next_example()

Func for_in_next_example()
    ConsoleWrite("For...In...Next Example" & @CRLF)

    Local $oJson   = Json_Decode($JSON_DATA)            ;Decode JSON string
    Local $aoItems = Json_Get($oJson, ".result.items")  ;Get array of "Items" objects
    Local $sName
    Local $iAge

    For $oItem in $aoItems
        $sName   = Json_Get($oItem, ".name")
        $iAge    = Json_Get($oItem, ".age")
        ConsoleWrite($sName & " is " & $iAge & @CRLF)
    Next
    ConsoleWrite(@CRLF)
EndFunc

Func for_next_example()
    ConsoleWrite("For...Next Example" & @CRLF)

    Local $oJson      = Json_Decode($JSON_DATA)            ;Decode JSON string
    Local $aoItems    = Json_Get($oJson, ".result.items")  ;Get array of "Items" objects
    Local $iItemCount = UBound(Json_Get($oJson, ".result.items"))
    Local $sName
    Local $iAge


    For $i = 0 To $iItemCount - 1
        $sName = Json_Get($aoItems[$i], ".name")
        $iAge  = Json_Get($aoItems[$i], ".age")
        ConsoleWrite($sName & " is " & $iAge & @CRLF)
    Next

    ConsoleWrite(@CRLF)
EndFunc

Output:

For...In...Next Example
Becky is 8
Dave is 6
Ashley is 7

For...Next Example
Becky is 8
Dave is 6
Ashley is 7

 

Very good example, need learn something, thank you

Link to comment
Share on other sites

  • 1 month later...
6 hours ago, samibb said:

where i can find "jsmn.au3" and download it.

The first result when you perform a search of jsmn.au3 with Google is (tata) : https://github.com/chechelaky/AutoIt/blob/master/JSMN.au3

EDIT : This link only serves archival purposes or if someone needs exactly this version.

Info to other users : Please use the download from the starting post. The jsmn.au3 was renamed and replaced by a revised version.

Edited by Musashi

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

  • Developers

Guess my point is that the initial post in this thread does contain the download for the supported JSON udfs in this thread, being json.au3, so why as for another file here ?

Jos 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

1 hour ago, Jos said:

Guess my point is, that the initial post in this thread does contain the download for the supported JSON udfs in this thread, being json.au3, so why as for another file here ?

@samibbhad explicitly asked for the jsmn.au3. Since @Ward deleted almost all his attachments, this was the latest version I found.

You are of course right, that the (among others by you) revised version from the initial post should be used. If @samibb would have read this post carefully, he would not have to look for the (outdated) jsmn.au3 ;).

However, I understand that my linking could mislead other users and will edit my post.

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

  On 5/6/2020 at 6:33 AM, samibb said:

where i can find "jsmn.au3" and download it.

The first result when you perform a search of jsmn.au3 with Google is (tata) : https://github.com/chechelaky/AutoIt/blob/master/JSMN.au3

EDIT : This link only serves archival purposes or if someone needs exactly this version.

Info to other users : Please use the download from the starting post. The jsmn.au3 was renamed and replaced by a revised version.

Edited May 6 by Musashi
 

Good morning,

I picked it up and after I found it I don't know how I didn't see it before lol ....

There is a zip file at the end of the first post that contains a latest update to json.au3.

I will not reply here so as not to lose the costume of looking there where to stay as to update.

Hugs, Clayson.

Link to comment
Share on other sites

  • 6 months later...

Hi all,

I was wondering how I can enumerate through the following keys and values under 'chars' in this JSON data:

{   
    "groups": [{
       "id": "6b365efb",
       "name": "Test1DoneA",
       "chars": [{
         "id": "45892dbd",
         "note": "testnote",
         "command": "open",
         "target": "/stats",
         "value": ""
       }]
    }]
}

Using the following

Local $Json1 = FileRead(@ScriptDir & "\mydata.json")
   Local $oJson = Json_Decode($Json1)
   Local $aoItems = Json_Get($oJson, ".groups[0].chars[0]")  
   For $oItem in $aoItems
      $sCommands   = Json_Get($oItem,???) ;Not sure what to put here to get every item under chars[0]
      ConsoleWrite("$sCommands: " & $sCommands & @CRLF)
   Next

 

Thanks

Link to comment
Share on other sites

Use Json_Dump() to get an idea of how to reference the values.

Link to comment
Share on other sites

Thanks @TheXman, I did but I was hoping there was a wildcard notation to just display the full string for each item.

In other words I'm not targeting a single item but want to list every item pair in characters.

#include "Json.au3"
;Local $Json1 = FileRead(@ScriptDir & "\mydata.json")
$Json1 = '{       "groups": [{     "id": "6b365efb",       "name": "Test1DoneA",       "chars": [{       "id": "45892dbd",       "note": "testnote",         "command": "open",      "target": "/stats",         "value": ""       }]    }]}'
Json_Dump($Json1)
   Local $oJson = Json_Decode($Json1)
   Local $aoItems = Json_Get($oJson, ".groups[0].chars[0]")
   For $oItem in $aoItems
      $sCommands   = Json_Get($oItem,???)
      ConsoleWrite("Item: " & $sCommands & @CRLF)
   Next



;~ {
;~     "groups": [{
;~     "id": "6b365efb",
;~     "name": "Test1DoneA",
;~     "chars": [{
;~       "id": "45892dbd",
;~       "note": "testnote",
;~       "command": "open",
;~       "target": "/stats",
;~       "value": ""
;~     }]
;~     }]
;~ }

So my result console output would be something like this:

Item: id = 45892dbd
Item: note = testnote
Item: command = open
Item: target = /stats
Item: value =

or something along those lines

Edited by NassauSky
Link to comment
Share on other sites

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#include <Constants.au3>
#include <json.au3>


example()

Func example()
    Const $JSON = _
        '{' & _
        '  "groups": [{' & _
        '     "id": "6b365efb",' & _
        '     "name": "Test1DoneA",' & _
        '     "chars": [{' & _
        '       "id": "45892dbd",' & _
        '       "note": "testnote",' & _
        '       "command": "open",' & _
        '       "target": "/stats",' & _
        '       "value": ""' & _
        '     }]' & _
        '  }]' & _
        '}'

    Local $oJson, $oChars

    $ojson  = Json_Decode($JSON)
    $oChars = Json_Get($ojson, ".groups[0].chars[0]")

    For $oKey in $oChars.Keys
        ConsoleWrite($oKey & " = " & $oChars.Item($oKey) & @CRLF)
    Next
EndFunc

Console:

id = 45892dbd
note = testnote
command = open
target = /stats
value =

 

Edited by TheXman
Link to comment
Share on other sites

Thanks @TheXman!

Jackpot: I just had this below alternative working but I like your method better since I didn't know we can use Key & Items to access the info.

#include "Json.au3"
$Json1 = '{"groups": [{"id": "6b365efb", "name": "Test1DoneA", "chars": [{"id": "45892dbd", "note": "testnote", "command": "open", "target": "/stats",       "value": ""}]}]}'

   Local $oJson = Json_Decode($Json1)
   Local $aoItems = Json_Get($oJson, ".groups[0].chars[0]")
   For $oItem in $aoItems
      ConsoleWrite($oItem & " = " & Json_Get($oJson, ".groups[0].chars[0]." & $oItem) & @CRLF)
   Next

 

Edited by NassauSky
Link to comment
Share on other sites

You're welcome.

If you look at the code in the json.au3 file, you will see that it stores json objects as dictionaries.  There are helper functions (JsonObj*) already in the json.au3 file that will let you access and manipulate those objects.  I just used the methods directly, instead of the helper functions, because I wanted to save a few keystrokes.  :)

Edited by TheXman
Link to comment
Share on other sites

I think I need another tip.  How about this. How would I get the count of groups in this example:

{   
    "groups": [{
       "id": "11",
       "name": "ItemA"
       },{
       "id": "22",
       "name": "ItemB"
       },{
       "id": "33",
       "name": "ItemC"
    }]
}

This isn't working:

Local $oJson = Json_Decode($Json1)
Local $aoItems = Json_Get($oJson, ".")
ConsoleWrite($aoItems.Count)

 

Edited by NassauSky
Link to comment
Share on other sites

$ojson   = Json_Decode($JSON)
$aGroups = Json_Get($ojson, ".groups")
ConsoleWrite("Groups count = " & UBound($aGroups) & @CRLF)

.groups is an array of json objects.  So you would get the count of how many array items like you would with any other array.

Edited by TheXman
Link to comment
Share on other sites

Correct, the value of .groups is an array, not a JSON object.

You're welcome. :)

Edited by TheXman
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...