Jump to content

A Non-Strict JSON UDF (JSMN)


Ward
 Share

Recommended Posts

The $auction you get from Jsmn_ObjGet($objJson, "a") is an object, not an array.

Your code should be modified like this:

#Include <JSMN.au3>

$JSON='{"a":{"742597609":{"v":673,"p":4.91,"lb":"test1","av":58,"sl":11.6},"534165346":{"v":777,"p":5.66,"lb":"test2","av":58,"sl":13.3}},"b":16092018}'

Local $objJson = Jsmn_Decode($JSON)

If Jsmn_IsObject($objJson) Then
    Local $auctions = Jsmn_ObjGet($objJson, "a")
    Local $Keys = Jsmn_ObjGetKeys($auctions)
    For $i = 0 To UBound($Keys) - 1
        Local $objJson2 = Jsmn_ObjGet($auctions, $Keys[$i])
        ConsoleWrite(Jsmn_ObjGet($objJson2, "p") & @LF)
    Next
EndIf

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Link to comment
Share on other sites

  • 2 weeks later...

I sometimes get this error:

JSMN.au3 (403) : ==> Error in expression.:
Return $Object.Item(String($Key))
Return ^ ERROR

I am trying to filter what is being decoded as JSON in the first place using StringRegExp on the input as well as using the Jsmn_IsObject function, but that sometimes doesn't seem to do the trick.

Does anyone know what could cause this error as well as what other error catching mechanism I could use to prevent it from happening ?

Link to comment
Share on other sites

  • 2 months later...

 

I wrote a helper function to get specific element in nested array/object returned from Jsmn_Decode() more easily.

Here is the code and example:

#Include "JSMN.au3"

Local $Json = '{"key1" : "value1", "key2" : [true, ["a", "b"], {"key3", "obj_in_array"}]}'
Local $Obj = Jsmn_Decode($Json)
Jsmn_Get_ShowResult($Obj, '["key1"]')
Jsmn_Get_ShowResult($Obj, '["key2"][0]')
Jsmn_Get_ShowResult($Obj, '["key2"][1][0]')
Jsmn_Get_ShowResult($Obj, '["key2"][2]["key3"]')

Local $Json = '{"strange key []" : "uses \\uXXXX for unsupported char in the key", "key_nospace_1" : {"key_nospace_2" : "don''t need \" if the key has no space"} }'
Local $Obj = Jsmn_Decode($Json)
Jsmn_Get_ShowResult($Obj, '["strange key [\u005D"]')
Jsmn_Get_ShowResult($Obj, '[key_nospace_1][key_nospace_2]')

Jsmn_Get_ShowResult($Obj, '[error1]')
Jsmn_Get_ShowResult($Obj, '[error2')


Func Jsmn_Get_ShowResult($Var, $Key)
    Local $Ret = Jsmn_Get($Var, $Key)
    If @Error Then
        Switch @error
            Case 1
                ConsoleWrite("Error 1: key not exists" & @LF)
            Case 2
                ConsoleWrite("Error 2: syntax error" & @LF)
        EndSwitch

    Else
        ConsoleWrite($Key & " => " & VarGetType($Ret) & ": " & $Ret & @LF)
    EndIf
EndFunc

Func Jsmn_Get($Var, $Key)
    If Not $Key Then Return $Var

    Local $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
    If IsArray($Match) Then
        Local $Index = Jsmn_Decode($Match[1])
        $Key = StringTrimLeft($Key, StringLen($Match[0]))

        If IsString($Index) And Jsmn_IsObject($Var) And Jsmn_ObjExists($Var, $Index) Then
            Local $Ret = Jsmn_Get(Jsmn_ObjGet($Var, $Index), $Key)
            Return SetError(@Error, 0, $Ret)

        ElseIf IsNumber($Index) And IsArray($Var) And $Index >= 0 And $Index < UBound($Var) Then
            Local $Ret = Jsmn_Get($Var[$Index], $Key)
            Return SetError(@Error, 0, $Ret)

        Else
            Return SetError(1, 0, "")

        EndIf
    EndIf

    Return SetError(2, 0, "")
EndFunc

Old thread I just needed to say Thanks

I spent Days trying to decode and use my Json file. I found and used your Code and it worked =)

Thanks a TON!!!!

The json part in my script

#Include "JSMN.au3"
#Include "File.au3"
local $Json1_2
_FileReadToArray(@ScriptDir & "\DatabaseS.db",$Json1_2,0)
$json1_3 = _ArrayToString($Json1_2,"")
$Json2 = StringStripWS($Json1_3, 8)
Local $Obj1 = Jsmn_Decode($Json2)
$resault = Jsmn_Get($Obj1, '["response"]["prices"]["10"]["6"]["0"]["last_update"]')
ConsoleWrite($resault & @CRLF)

Func Jsmn_Get($Var, $Key)
    If Not $Key Then Return $Var

    Local $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
    If IsArray($Match) Then
        Local $Index = Jsmn_Decode($Match[1])
        $Key = StringTrimLeft($Key, StringLen($Match[0]))

        If IsString($Index) And Jsmn_IsObject($Var) And Jsmn_ObjExists($Var, $Index) Then
            Local $Ret = Jsmn_Get(Jsmn_ObjGet($Var, $Index), $Key)
            Return SetError(@Error, 0, $Ret)

        ElseIf IsNumber($Index) And IsArray($Var) And $Index >= 0 And $Index < UBound($Var) Then
            Local $Ret = Jsmn_Get($Var[$Index], $Key)
            Return SetError(@Error, 0, $Ret)

        Else
            Return SetError(1, 0, "")

        EndIf
    EndIf

    Return SetError(2, 0, "")
EndFunc
Edited by Siahtech
Link to comment
Share on other sites

  • 3 weeks later...

I am completely unable to understand how to access arrays using the latest JSMN.au3 downloaded from the first post, Jsmn_Get from >post #12 and dot notation. In fact, that Jsmn_Get doesn't seem to be working with old-style notation either. Can someone redo or recommend a way to access json information with dot notation that actually works?

 

#Include "JSMN.au3"

Local $Json = '{"events":[{"world_id":2012,"map_id":873,"event_id":"659149D4-43EC-4DCB-A6BB-0B2D402B537B","state":"Warmup"},{"world_id":2012,"map_id":873,"event_id":"72F93CD8-94AC-4234-8D86-996CCAC76A46","state":"Warmup"},{"world_id":2012,"map_id":873,"event_id":"81F89AC2-4764-49CB-A4F1-8B7546201DC7","state":"Active"},{"world_id":2012,"map_id":873,"event_id":"FF71DE90-423B-4685-A343-83487A330C7A","state":"Active"}]}'
Local $Obj = Jsmn_Decode($Json)

ConsoleWrite(Jsmn_Get($Obj, "events[0].world_id") & @CRLF) ;Doesn't work
ConsoleWrite(Jsmn_Get($Obj, '["events"][0]["world_id"]', 1) & @LF) ;Doesn't work

; #FUNCTION# ===================================================================
; Name:             Jsmn_Get
; Description:    Retrieves a value from the scripting.dictionary key specified
;
; Parameter(s):
;                       $Object     Scripting dictionary object
;
;                       $Key        Key for the value you want to retrieve. Follows delimiter based or JSON based format depending on the notation parameter
;
;                       $Notation
;                                       0 - Delimiter based - Key1.Key2
;                                       1 - JSON format based ["key1"]["key2"]
;
;                       $Delim      If notation = 0 Then this is the delimiter between keys
;
; Requirement(s):   JSMN JSON library by Ward.
;
; Return Value(s):
;                           On Success  Returns value from key
;
;                           On Failure      Returns a blank string and an error value.
;                                               @error
;                                                   1 - key does not exist
;                                                   2 - notation syntax error
;                                               @Extended - Only used if notation = 0
;                                                   See StringSplit error codes
;
; Author(s):    Ward (modified slightly by SantaRyan to add delimiter notation)
;===============================================================================
Func Jsmn_Get($Object, $Key, $Notation = 0, $Delim = ".")
    If Not $Key Then Return $Object
    If IsKeyword($Notation) Then $Notation = 0
    Local $Index, $Match, $Ret
    If $Notation = 0 Then
        $Match = StringSplit($Key, $Delim, 1)
        If IsArray($Match) Then
            $Index = $Match[1]
            $Key = ""
            For $i = 2 To $Match[0]
                $Key &= $Match[$i] & $Delim
            Next
            $Key = StringTrimRight($Key, 1)
        Else
            Return SetError(2, 0, "")
        EndIf
    ElseIf $Notation = 1 Then
        $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
        If IsArray($Match) Then
            $Index = Jsmn_Decode($Match[1])
            $Key = StringTrimLeft($Key, StringLen($Match[0]))
        Else
            Return SetError(2, 0, "")
        EndIf
    EndIf
    If IsString($Index) And Jsmn_IsObject($Object) And Jsmn_ObjExists($Object, $Index) Then
        $Ret = Jsmn_Get(Jsmn_ObjGet($Object, $Index), $Key, $Delim)
        Return SetError(@error, 0, $Ret)
    ElseIf IsNumber($Index) And IsArray($Object) And $Index >= 0 And $Index < UBound($Object) Then
        $Ret = Jsmn_Get($Object[$Index], $Key, $Delim)
        Return SetError(@error, 0, $Ret)
    Else
        Return SetError(1, 0, "")
    EndIf
EndFunc   ;==>Jsmn_Get
Edited by this-is-me
Who else would I be?
Link to comment
Share on other sites

24-hr bump. I really want to use dot notation to access JSON objects using JSMN. If someone can "fix" the existing code, or rewrite it I would appreciate it. I don't begin to understand what to do with it.

EDIT: After much trouble, I realise two problems with Jsmn_Get. First, the $Index was not being typecast as a number in the case of a dot notation. Therefore, I added a simple typecast.
 

$Index = $Match[1]
;Add the following
$Index = (StringIsInt($Index)=1?Number($Index):$Index)

Secondly, when the function was called by itself, it was called with improper parameters (missing the notation flag):
 

;OLD: $Ret = Jsmn_Get(Jsmn_ObjGet($Object, $Index), $Key, $Delim)
$Ret = Jsmn_Get(Jsmn_ObjGet($Object, $Index), $Key, $Notation, $Delim)

;OLD: $Ret = Jsmn_Get($Object[$Index], $Key, $Delim)
$Ret = Jsmn_Get($Object[$Index], $Key, $Notation, $Delim)

With these problems solved, everything works swimmingly.

Edited by this-is-me
Who else would I be?
Link to comment
Share on other sites

  • 1 month later...

Great UDF, been using it to work with JSON much easier than other functions.  I'm also using Jsmn_Get (which is a massive time saver).

However, getting this one string to decode properly has me stumped.

The Decode function shows no error (which there isn't that I can find separating it manually - see the commented section), though $JSMN_PRETTY_PRINT does not break the "groups" out properly (at least, that is what it seems to me).

What am I missing?

#Include "JSMN.au3"

Test3()

Func Test3()

Local $string2test = '{"id":"6","username":"USERNAME","firstName":"FirstName","lastName":"LastName","emailAddress":"example@example.com","phoneNumber":"","lastLogin":"","statusId":"1","timezone":"America\/Chicago","organization":"","position":"","language":"en_us","icsUrl":null,"customAttributes":[{"id":"5","label":"user attribute","value":null,"links":[{"href":"http:\/\/example.com\/Attributes\/5","title":"get_custom_attribute"}],"message":null}],"permissions":[{"id":"1","name":"","links":[{"href":"http:\/\/example.com\/Resources\/1","title":"get_resource"}],"message":null},{"id":"2","name":"","links":[{"href":"http:\/\/example.com\/Resources\/2","title":"get_resource"}],"message":null}],"groups":[{"links":[{"href":"http:\/\/example.com\/Groups\/1","title":"get_group"}],"message":null,"id":"1","name":"Administrators"},{"links":[{"href":"http:\/\/example.com\/Groups\/5","title":"get_group"}],"message":null,"id":"5","name":"Students"}],"links":[],"message":null}'

    Local $Json1    = $string2test
    Local $Data1 = Jsmn_Decode($Json1)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Data1 = ' & $Data1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    Local $Json2 = Jsmn_Encode($Data1, $JSMN_UNQUOTED_STRING)
    Local $Data2 = Jsmn_Decode($Json2)

    Local $Json3 = Jsmn_Encode($Data2, $JSMN_PRETTY_PRINT, "  ", "\n", "\n", "")
    Local $Data3 = Jsmn_Decode($Json3)

    Local $Json4 = Jsmn_Encode($Data1, $JSMN_STRICT_PRINT)

    ConsoleWrite("Test3 Unquoted Result: " & $Json2 & @CRLF)
    ConsoleWrite("Test3 Pretty Result: " & $Json3 & @CRLF)
    Return (StringLen($Json3) >= StringLen($Json1))
EndFunc

#cs
    Here is how the string breaks down (manually)
    NOTE HOW GROUPS COMES OUT CORRECTLY
{
    "id":"6",
    "username":"USERNAME",
    "firstName":"FirstName",
    "lastName":"LastName",
    "emailAddress":"example@example.com",
    "phoneNumber":"",
    "lastLogin":"",
    "statusId":"1",
    "timezone":"America\/Chicago",
    "organization":"",
    "position":"",
    "language":"en_us",
    "icsUrl":null,
    "customAttributes": [
        {
            "id":"5",
            "label":"user attribute",
            "value":null,
            "links":[
                {
                    "href":"http:\/\/example.com\/Attributes\/5",
                    "title":"get_custom_attribute"
                }
            ],
            "message":null
        }
    ],
    "permissions":[
        {
            "id":"1",
            "name":"",
            "links":[
                {
                    "href":"http:\/\/example.com\/Resources\/1",
                    "title":"get_resource"
                }
            ],
            "message":null
        },
        {
            "id":"2",
            "name":"",
            "links":[
                {
                    "href":"http:\/\/example.com\/Resources\/2",
                    "title":"get_resource"
                }
            ],
            "message":null
        }
    ],
    "groups":[             <<<<======= HERE, IT IS CORRECT - THOUGH CHECK YOUR CONSOLE OUTPUT!
        {
            "links":[
                {
                    "href":"http:\/\/example.com\/Groups\/1",
                    "title":"get_group"
                }
            ],
            "message":null,
            "id":"1",
            "name":"Administrators"
        },
        {
            "links":[
                {
                    "href":"http:\/\/example.com\/Groups\/5",
                    "title":"get_group"
                }
            ],
            "message":null,
            "id":"5",
            "name":"Students"
        }
    ],
    "links":[],
    "message":null
}
#ce
Link to comment
Share on other sites

Guys, i can't get this magic ...

here is my JSON array

[

  {

    "Sysinfo": [

      {

        "Name": "System",

        "Description": "System",

        "Type": "System",

        "Capabilities": "System",

        "Manufacturer": "",

        "Properties": [

          {

            "Name": "User Application Total Space",

            "Description": "The total space for user applications on the device.",

            "Type": "DISCRETEMEASUREMENT",

            "Value": "5.42 GB"

          },

          {

            "Name": "User Application Percentage Free Space",

            "Description": "The percentage of free space for user applications on the device.",

            "Type": "PERCENT",

            "Value": "0.949643"

          },

          {

            "Name": "Android Build Id",

            "Description": "The version of Android running on the system",

            "Type": "STRING",

            "Value": "JDQ39"

          }

        ]

      }

    ]

  },

  {

    "Scripts": [

      {

        "Script": "123a",

        "Date": "Mar 24, 2014 12:52:31 PM",

        "Result": "Failed",

        "Tests": [

          {

            "Name": "APT",

            "Device": "System Memory",

            "Result": "Pass"

          }

        ]

      }

    ]

  }

]

i try to adapt this:

local $Json1_2
_FileReadToArray("TestHistory.txt",$Json1_2)
$json1_3 = _ArrayToString($Json1_2,"")
$Json2 = StringStripWS($Json1_3, 8)
Local $Obj1 = Jsmn_Decode($Json2)
$resault = Jsmn_Get($Obj1, '[0]["Sysinfo"]["0"]["7"]["User Application Total Space"]')
ConsoleWrite($resault & @CRLF)

but all time i cant get resoults, maybe its to complicated for me :D

any help ?

thxx

Edited by lxxl
Link to comment
Share on other sites

Not sure what you are trying to get from the string (as your code shows you asking for the result name, not the variable...)

you will see that, at the end (if not before) you are asking for the "User Application Tool Space", which is the RESULT - you should be asking for, perhaps 'Name' there - so the result can come back - example on that below

Here is a tip on how I got used to using the UDF and JSON in general.

Take it a step at a time!

instead of 

$resault = Jsmn_Get($Obj1, '[0]["Sysinfo"]["0"]["7"]["User Application Total Space"]')

just go to

$resault = Jsmn_Get($Obj1, '[0]')

and see what you get (should be something you recognize)

then, the next bit (once you select what you really want)

$resault = Jsmn_Get($Obj1, '[0]["Sysinfo"]')

etc.

Like the old saying - you CAN eat an elephant, just take it in small bites - and keep at it until you are done.

 

the way I look at it is, for a START,

1. replace [{ with a [0]

(start with 0 and go from there until you get what you want...)

2. if you find the variable you want in the list, add that to your 'get' string

3. go back to step 1 when needed

Now, to get the result of "User Application Tool Space" as I believe you are looking for in your example, you need to look at;

[0]['Sysinfo'][[0]['Properties'][0]['Name']

More simple now?

Link to comment
Share on other sites

Yeah, I now see what it is...... - you are trying too hard!

Not sure what all that Array stuff is - you don't need it when working with JSON - it, by definition, is an array-decrypter (of sorts) - whatever you call it, JSON is a method in/of itself and you are trying to tear it apart yourself, then looking for the tools to do the work.

Don't try so hard!  ;)

Basically, all you need when using this UDF: 

1. take the incoming JSON code (in your case, coming from a .txt file - it might come from a result or anywhere... - but LEAVE IT ALONE AS JSON)

2. JSMN_DECODE it to an object.  

3. use JSMN_GET.  

That's it!

This works (using the demo from JSMN and your data to show you the full results) - notice you only need ONE include, which is this UDF!

#include "JSMN.au3"


local $Json1
$Json1 = FileRead("TestHistory.txt")
Local $Data1 = Jsmn_Decode($Json1)

; ************************************************************************************
; these lines are NOT NEEDED in your live system, just here to show the output
Local $Json2 = Jsmn_Encode($Data1, $JSMN_UNQUOTED_STRING)
Local $Data2 = Jsmn_Decode($Json2)
Local $Json3 = Jsmn_Encode($Data2, $JSMN_PRETTY_PRINT, "  ", "\n", "\n", "")
ConsoleWrite("Test3 Unquoted Result: " & $Json2 & @CRLF)
ConsoleWrite("Test3 Pretty Result: " & $Json3 & @CRLF)
; the above lines are not needed in a live system
; ************************************************************************************

$resault = Jsmn_Get($Data1, '[0]["Sysinfo"][0]["Properties"][0]["Name"]')
ConsoleWrite($resault & @CRLF)

and, for future reference, when you post code - go ahead and put in the #includes you are using (makes it simpler for someone testing your code, as well as know what you are using - it might be that you have the wrong includes sometimes....)

So, end result - let the tool do the work.  

(BTW, my 'tip' on going step at a time didn't work on this - because it starts off with an array - the data I have been working with is a bit different and that stepping through worked for me - guess it all depends on the data  :   However, the 'replace [{ with [0] works on your data as well as mine, so that seems a good 'rule'... :sweating: )

Link to comment
Share on other sites

hey TechCoder, thxx for code now all looks better with

ConsoleWrite("Test3 Unquoted Result: " & $Json2 & @CRLF)

i can get this in console

>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\x\Desktop\code\log.au3" /UserParams    
+>07:42:25 Starting AutoIt3Wrapper v.2.1.0.8    Environment(Language:0409  Keyboard:00000415  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64)
>Running AU3Check (1.54.22.0)  from:C:\Program Files (x86)\AutoIt3
+>07:42:25 AU3Check ended.rc:0
>Running:(3.3.8.1):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\x\Desktop\code\log.au3"    
Test3 Unquoted Result: [{Sysinfo:[{Name:System,Description:System,Type:System,Capabilities:System,Manufacturer:,Properties:[{Name:"User Application Total Space",Description:"The total space for user applications on the device.",Type:DISCRETEMEASUREMENT,Value:"5.42 GB"},{Name:"User Application Percentage Free Space",Description:"The percentage of free space for user applications on the device.",Type:PERCENT,Value:"0.949643"},{Name:"Android Build Id",Description:"The version of Android running on the system",Type:STRING,Value:JDQ39}]}]},{Scripts:[{Script:"123a",Date:"Mar 24, 2014 12:52:31 PM",Result:Failed,Tests:[{Name:APT,Device:"System Memory",Result:Pass}]}]}]

+>07:42:25 AutoIT3.exe ended.rc:0
>Exit code: 0    Time: 1.650

 

so code is working !, move over

Local $Json3 = Jsmn_Encode($Data2, $JSMN_PRETTY_PRINT, "  ", "\n", "\n", "")

print 1:1 txt file and this is good as well

but this damm code give me only @CR

$resault = Jsmn_Get($Data1, '[0]["Sysinfo"][0]["Properties"][0]["Name"]')
ConsoleWrite($resault & @CRLF)

with Func Jsmn_Get do you have this one:

; #FUNCTION# ===================================================================
; Name:             Jsmn_Get
; Description:    Retrieves a value from the scripting.dictionary key specified
;
; Parameter(s):
;                       $Object     Scripting dictionary object
;
;                       $Key        Key for the value you want to retrieve. Follows delimiter based or JSON based format depending on the notation parameter
;
;                       $Notation
;                                       0 - Delimiter based - Key1.Key2
;                                       1 - JSON format based ["key1"]["key2"]
;
;                       $Delim      If notation = 0 Then this is the delimiter between keys
;
; Requirement(s):   JSMN JSON library by Ward.
;
; Return Value(s):
;                           On Success  Returns value from key
;
;                           On Failure      Returns a blank string and an error value.
;                                               @error
;                                                   1 - key does not exist
;                                                   2 - notation syntax error
;                                               @Extended - Only used if notation = 0
;                                                   See StringSplit error codes
;
; Author(s):    Ward (modified slightly by SantaRyan to add delimiter notation)
;===============================================================================
Func Jsmn_Get($Object, $Key, $Notation = 0, $Delim = ".")
    If Not $Key Then Return $Object
    If IsKeyword($Notation) Then $Notation = 0
    Local $Index, $Match, $Ret
    If $Notation = 0 Then
        $Match = StringSplit($Key, $Delim, 1)
        If IsArray($Match) Then
            $Index = $Match[1]
            $Key = ""
            For $i = 2 To $Match[0]
                $Key &= $Match[$i] & $Delim
            Next
            $Key = StringTrimRight($Key, 1)
        Else
            Return SetError(2, 0, "")
        EndIf
    ElseIf $Notation = 1 Then
        $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
        If IsArray($Match) Then
            $Index = Jsmn_Decode($Match[1])
            $Key = StringTrimLeft($Key, StringLen($Match[0]))
        Else
            Return SetError(2, 0, "")
        EndIf
    EndIf
    If IsString($Index) And Jsmn_IsObject($Object) And Jsmn_ObjExists($Object, $Index) Then
        $Ret = Jsmn_Get(Jsmn_ObjGet($Object, $Index), $Key, $Delim)
        Return SetError(@error, 0, $Ret)
    ElseIf IsNumber($Index) And IsArray($Object) And $Index >= 0 And $Index < UBound($Object) Then
        $Ret = Jsmn_Get($Object[$Index], $Key, $Delim)
        Return SetError(@error, 0, $Ret)
    Else
        Return SetError(1, 0, "")
    EndIf
EndFunc   ;==>Jsmn_Get

?

Link to comment
Share on other sites

I'm really not understanding your post - again, please put in the full code because your message is mixed - "works!" and "not" in one - not sure if you took out something or what from the code I gave you, which works fine and as expected on my system.

And, yes, you do have to add in the jsmn_get function to the UDF (I did that in my copy the first day - forgot about that.... - the one that coded it said he would add it but it is not in the first post download - yes, you have to have it as well - either in the UDF or in the program you are using....) - though if you are not getting errors on that, it seems you have that function (pulled from another post is what I use.)

Is that the problem you are discussing?  Again, just not clear (I'm in the middle of a big project and can only glance at the replies - if they aren't 'easy' to figure out, I have to move on {i.e., helping others with their coding issue is not my primary job - but I do what I can...})   When asking for help, I try to follow a tip an old-timer told me years ago "Before you post, check to make sure a 3rd grader can understand it" - then, there is no guessing for the person trying to help you.

Link to comment
Share on other sites

  • 4 months later...

I am trying to use this UDF and keep getting stuck. This is the code I have:

$json1 = '{"coord":{"lon":-0.13,"lat":51.51},"sys":{"type":1,"id":5091,"message":0.2133,"country":"GB","sunrise":1406607636,"sunset":1406663600},"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01n"}],"base":"cmc stations","main":{"temp":295.47,"pressure":1014,"humidity":47,"temp_min":293.15,"temp_max":298.15},"wind":{"speed":5.1,"deg":340},"clouds":{"all":0},"dt":1406664059,"id":2643743,"name":"London","cod":200}'
$jsmn = Jsmn_Decode($json1)

$object = Jsmn_ObjGet($jsmn, "coord")
$keys = Jsmn_ObjGetKeys($object)
_ArrayDisplay($keys)

At this point I get an array with "lun" and "lat".
 
How would I actually get the value of these 2 keys?
 
Additionally, why if I try to get the "weather" key, am I not getting any return?
 
 
Thank you I really appreciate the hard work you guys put into developing these UDF's.

Edited by tes5884
Link to comment
Share on other sites

To get value in object, just use Jsmn_ObjGet.

In your json, weather is an array, and array[0] is an object.

After you got $jsmn object decoded from the $json1 string, try this code.

$coord = Jsmn_ObjGet($jsmn, "coord")
ConsoleWrite(Jsmn_ObjGet($coord, "lon") & @LF)
ConsoleWrite(Jsmn_ObjGet($coord, "lat") & @LF)

$weather = Jsmn_ObjGet($jsmn, "weather")
For $key In $weather[0]
    ConsoleWrite(StringFormat("%s => %s\n", $key, Jsmn_ObjGet($weather[0], $key)))
Next

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Link to comment
Share on other sites

 

To get value in object, just use Jsmn_ObjGet.

In your json, weather is an array, and array[0] is an object.

After you got $jsmn object decoded from the $json1 string, try this code.

$coord = Jsmn_ObjGet($jsmn, "coord")
ConsoleWrite(Jsmn_ObjGet($coord, "lon") & @LF)
ConsoleWrite(Jsmn_ObjGet($coord, "lat") & @LF)

$weather = Jsmn_ObjGet($jsmn, "weather")
For $key In $weather[0]
    ConsoleWrite(StringFormat("%s => %s\n", $key, Jsmn_ObjGet($weather[0], $key)))
Next

That worked. Thank you!

Link to comment
Share on other sites

  • 1 month later...

In case you're feeling lost, here's a little helper function that lists up all accessible items // based on ward's cool stuff. Cheers

#include "JSMN.au3"
#include <array.au3>
#include <file.au3>

Local $filelist = _FileListToArray(@ScriptDir, "*.json")
Local $i, $json, $obj

For $i = 1 To $filelist[0]
    ConsoleWrite("-----------" & $filelist[$i] & "----------------" & @CRLF)
    $json = FileRead($filelist[$i])
    $obj = Jsmn_Decode($json)
    Jsmn_Iterate($obj, '', $filelist[$i])
Next

Func Jsmn_Iterate($obj, $string, $pre = "")
    Local $temp, $i, $b

    If ($pre <> "") Then ConsoleWrite($pre & ": ")

    $a = Jsmn_Get_ShowResult($obj, $string)
    If IsArray($a) Then
        For $i = 0 To UBound($a) - 1
            Jsmn_Iterate($obj, $string & '[' & $i & ']', $pre)
        Next
    ElseIf IsObj($a) Then
        $b = Jsmn_ObjGetKeys($a)
        For $temp In $b
            Jsmn_Iterate($obj, $string & '["' & $temp & '"]', $pre)
        Next
    EndIf
    Return
EndFunc   ;==>Jsmn_Iterate

Func Jsmn_Get_ShowResult($Var, $Key)
    Local $Ret = Jsmn_Get($Var, $Key)
    If @error Then
        Switch @error
            Case 1
                ConsoleWrite("Error 1: key not exists" & @LF)
            Case 2
                ConsoleWrite("Error 2: syntax error" & @LF)
        EndSwitch

    Else
        ConsoleWrite($Key & " => " & VarGetType($Ret) & ": " & $Ret & @LF)
    EndIf
    Return $Ret
EndFunc   ;==>Jsmn_Get_ShowResult

Func Jsmn_Get($Var, $Key)
    If Not $Key Then Return $Var

    Local $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
    If IsArray($Match) Then
        Local $Index = Jsmn_Decode($Match[1])
        $Key = StringTrimLeft($Key, StringLen($Match[0]))

        If IsString($Index) And Jsmn_IsObject($Var) And Jsmn_ObjExists($Var, $Index) Then
            Local $Ret = Jsmn_Get(Jsmn_ObjGet($Var, $Index), $Key)
            Return SetError(@error, 0, $Ret)

        ElseIf IsNumber($Index) And IsArray($Var) And $Index >= 0 And $Index < UBound($Var) Then
            Local $Ret = Jsmn_Get($Var[$Index], $Key)
            Return SetError(@error, 0, $Ret)

        Else
            Return SetError(1, 0, "")

        EndIf
    EndIf

    Return SetError(2, 0, "")
EndFunc   ;==>Jsmn_Get
Edited by poolcat
Link to comment
Share on other sites

  • 4 months later...

== Update 2015/01/08 ==
* Rename the library from jsmn.au3 to json.au3. All function names are changed, too.
* Add Json_Put() and Json_Get()
* Add Null support
* Using BinaryCall.au3 to loading the machine code.

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Link to comment
Share on other sites

  • 2 weeks later...

 

In case you're feeling lost, here's a little helper function that lists up all accessible items // based on ward's cool stuff. Cheers

#include "JSMN.au3"

Thanks much for your code. I touch up your code to work with the new UDF.

#include "JSON.au3"
#include <file.au3>

Local $filelist = _FileListToArray(@ScriptDir, "*.json")
Local $i, $json, $obj

For $i = 1 To $filelist[0]
    ConsoleWrite("-----------" & $filelist[$i] & "----------------" & @CRLF)
    $json = FileRead($filelist[$i])
    $obj = Json_Decode($json)
    Json_Iterate($obj, '', $filelist[$i])
Next

Func Json_Iterate($obj, $string, $pre = "")
    Local $temp, $i, $b
    If ($pre <> "") Then ConsoleWrite($pre & ": ")
    $a = Json_Get_ShowResult($obj, $string)
    If IsArray($a) Then
        For $i = 0 To UBound($a) - 1
            Json_Iterate($obj, $string & '[' & $i & ']', $pre)
        Next
    ElseIf IsObj($a) Then
        $b = Json_ObjGetKeys($a)
        For $temp In $b
            Json_Iterate($obj, $string & '["' & $temp & '"]', $pre)
        Next
    EndIf
    Return
EndFunc   ;==>Json_Iterate

Func Json_Get_ShowResult($Var, $Key)
    Local $Ret = Json_Getr($Var, $Key)
    If @error Then
        Switch @error
            Case 1
                ConsoleWrite("Error 1: key not exists" & @LF)
            Case 2
                ConsoleWrite("Error 2: syntax error" & @LF)
        EndSwitch
    Else
        ConsoleWrite($Key & " => " & VarGetType($Ret) & ": " & $Ret & @LF)
    EndIf
    Return $Ret
EndFunc   ;==>Json_Get_ShowResult

Func Json_Getr($Var, $Key)
    If Not $Key Then Return $Var
    Local $Match = StringRegExp($Key, "(^\[([^\]]+)\])", 3)
    If IsArray($Match) Then
        Local $Index = Json_Decode($Match[1])
        $Key = StringTrimLeft($Key, StringLen($Match[0]))
        If IsString($Index) And Json_IsObject($Var) And Json_ObjExists($Var, $Index) Then
            Local $Ret = Json_Getr(Json_ObjGet($Var, $Index), $Key)
            Return SetError(@error, 0, $Ret)
        ElseIf IsNumber($Index) And IsArray($Var) And $Index >= 0 And $Index < UBound($Var) Then
            Local $Ret = Json_Getr($Var[$Index], $Key)
            Return SetError(@error, 0, $Ret)
        Else
            Return SetError(1, 0, "")
        EndIf
    EndIf
    Return SetError(2, 0, "")
EndFunc   ;==>Json_Getr

So my problem is solved.

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

  • 2 weeks later...

Need some help getting values out of this JSON.  Any ideas on how to access the value "ThisIsWhatIWant"...?

Here's my json...

{ 
"Headers":[ 
{ 
"Name":"LOGICAL_NAME",
"Type":"VARCHAR2"
}
],
"ColumnCount":1,
"Rows":[ 
{ 
"Cells":[ 
"ThisIsWhatIWant"
],
"CellCount":1
}
]
}

And this is my non-working code attempt...

#include <JSon.au3>

$Json1 = '{ "Headers":[ { "Name":"LOGICAL_NAME","Type":"VARCHAR2"}],"ColumnCount":1,"Rows":[ { "Cells":[ "ThisIsWhatIWant"],"CellCount":1}]}'

Local $objJson = Json_Decode($Json1)
If (json_IsObject($objJson)) Then

;~ ConsoleWrite('Data1:' & json_ObjGetKeys($objJson) & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, "ColumnCount") & @CRLF);this line just to prove I can access something
ConsoleWrite('Data2:' & json_ObjGet($objJson, '["Rows"]["Cells"]') & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, '["Rows"][0]["Cells"]') & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, "['Rows']['Cells']") & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, '["Rows"]["Cells"]') & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, '["Rows"][0]["Cells"]') & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, "Rows.Cells[1]") & @CRLF)
ConsoleWrite('Data2:' & json_ObjGet($objJson, '["Rows"][0]["Cells"]') & @CRLF)
 ConsoleWrite('Data3:' & json_ObjGetCount($objJson) & @CRLF)
  ConsoleWrite('Data4:' & json_ObjExists($objJson, "Rows") & @CRLF)
Else
    ConsoleWrite("no an object")
EndIf

Thanks

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...