Jump to content
Ward

A Non-Strict JSON UDF (JSMN)

Recommended Posts

Hey,

thanks for the UDF, good work. But I have problems with a specific json source -> http://data.mtgox.com/api/1/BTCUSD/depth

I can't extract the values. First I used the other JSON UDF from Gabriel Boehme and I have exactly the same problems.

I get an empty array with ~500 elements when I get into the asks or bids arrays.

This is what I'm doing to get the data:

Func getArrayFromJson($URI,$reqAuth,$post="")
$result = Jsmn_Decode(goxRequest($URI,_Iif($reqAuth>0,getNonce()&$post,"")))
$result = Jsmn_ObjTo2DArray($result)
If (Not IsArray($result) Or UBound($result) = 0) Then
MsgBox(0,"Error: "&$URI,$result)
Return 0
Else
If(NOT IsArray($result[2][1])) Then
MsgBox(0,$URI,$result[2][1])
Return 0
EndIf
Return $result[2][1]
EndIf
EndFunc

It works on every other API without problems, just not with this one.

Share this post


Link to post
Share on other sites

Try this code, then your will see every element is decoded succeed.

#Include "JSMN.au3"

Local $Json = BinaryToString(InetRead("http://data.mtgox.com/api/1/BTCUSD/depth"), 4)
Local $Obj = Jsmn_Decode($Json)

ConsoleWrite(Jsmn_Encode($Obj, $JSMN_PRETTY_PRINT))

Then why you got empty output?

Because in your code, "$result[2][1]" is an array, so you can't use MsgBox to output it.


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

 

Share this post


Link to post
Share on other sites

Hey Ward,

fist of all thanks for JSON extension! I appreciate the work you spent to help this community with your programming skills!

I am new to this forum and autoit is one of my personal interests so I would like to say "Hello everyone" :bye:.

Maybe someone can help me with my question?:

I want to query a JSON wheather service to get the actual wheater and for future use also the forecast.

For this I use OperWheatherMap API and build my JSON, e.g. for today in Berlin:

{"cod":"200","message":0.0268,"city":{"id":2950159,"name":"Berlin","coord":{"lon":13.41053,"lat":52.524368},"country":"DE","population":1000000},"cnt":1,"list":[{"dt":1368874800,"temp":{"day":13.22,"min":10.57,"max":13.22,"night":10.57,"eve":12.49,"morn":13.22},"pressure":1015.76,"humidity":100,"weather":[{"id":501,"main":"Rain","description":"mäßiger Regen","icon":"10"}],"speed":7.08,"deg":269,"clouds":92,"rain":7.75}]}

My special interest lays in the params "temp":{"day":13.22,"min":10.57,"max":13.22 ... and  "description":"mäßiger Regen" but I am not able to extract this information using JSMN.

My code:

#include <JSMN.au3>

; Anfrage von Wetter mit JSON Antwort: http://api.openweathermap.org/data/2.5/forecast/daily?q=Berlin&mode=json&units=metric&cnt=1&lang=de
local $Json1 = '{"cod":"200","message":0.0268,"city":{"id":2950159,"name":"Berlin","coord":{"lon":13.41053,"lat":52.524368},"country":"DE","population":1000000},"cnt":1,"list":[{"dt":1368874800,"temp":{"day":13.22,"min":10.57,"max":13.22,"night":10.57,"eve":12.49,"morn":13.22},"pressure":1015.76,"humidity":100,"weather":[{"id":501,"main":"Rain","description":"mäßiger Regen","icon":"10"}],"speed":7.08,"deg":269,"clouds":92,"rain":7.75}]}'

Local $objJson = Jsmn_Decode($Json1)
If (Jsmn_IsObject($objJson)) Then
    ConsoleWrite('Data1:' & Jsmn_ObjGetKeys($objJson) & @CRLF)
    ConsoleWrite('Data2:' & Jsmn_ObjGet($objJson, "message") & @CRLF)
    ConsoleWrite('Data3:' & Jsmn_ObjGetCount($objJson) & @CRLF)
    ConsoleWrite('Data4:' & Jsmn_ObjExists($objJson, "message") & @CRLF)
Else
    ConsoleWrite("Kein Objekt")
EndIf

The according console output:

Data1:
Data2:0.0268
Data3:5
Data4:True

So the first level was queried successfully but if I want to query the params mentioned above I get an empty result:

AutoIt:

#include <JSMN.au3>

; Anfrage von Wetter mit JSON Antwort: http://api.openweathermap.org/data/2.5/forecast/daily?q=Berlin&mode=json&units=metric&cnt=1&lang=de
local $Json1 = '{"cod":"200","message":0.0268,"city":{"id":2950159,"name":"Berlin","coord":{"lon":13.41053,"lat":52.524368},"country":"DE","population":1000000},"cnt":1,"list":[{"dt":1368874800,"temp":{"day":13.22,"min":10.57,"max":13.22,"night":10.57,"eve":12.49,"morn":13.22},"pressure":1015.76,"humidity":100,"weather":[{"id":501,"main":"Rain","description":"mäßiger Regen","icon":"10"}],"speed":7.08,"deg":269,"clouds":92,"rain":7.75}]}'
Local $objJson = Jsmn_Decode($Json1)
If (Jsmn_IsObject($objJson)) Then
    ConsoleWrite('Data1:' & Jsmn_ObjGetKeys($objJson) & @CRLF)
    ConsoleWrite('Data2:' & Jsmn_ObjGet($objJson, "day") & @CRLF)
    ConsoleWrite('Data3:' & Jsmn_ObjGetCount($objJson) & @CRLF)
    ConsoleWrite('Data4:' & Jsmn_ObjExists($objJson, "day") & @CRLF)
Else
    ConsoleWrite("Kein Objekt")
EndIf
Local $objJson2 = Jsmn_Decode($objJson)

Console:

Data1:
Data2:
Data3:6
Data4:True

Because this is my first contact with JSON I think that I am doing something wrong with the the function "Jsmn_ObjGet". But what am I doing wrong?

Regards

mmscripting

Share this post


Link to post
Share on other sites

Try this:

#include <JSMN.au3>

; Anfrage von Wetter mit JSON Antwort: http://api.openweathermap.org/data/2.5/forecast/daily?q=Berlin&mode=json&units=metric&cnt=1&lang=de
local $Json1 = '{"cod":"200","message":0.0268,"city":{"id":2950159,"name":"Berlin","coord":{"lon":13.41053,"lat":52.524368},"country":"DE","population":1000000},"cnt":1,"list":[{"dt":1368874800,"temp":{"day":13.22,"min":10.57,"max":13.22,"night":10.57,"eve":12.49,"morn":13.22},"pressure":1015.76,"humidity":100,"weather":[{"id":501,"main":"Rain","description":"mäßiger Regen","icon":"10"}],"speed":7.08,"deg":269,"clouds":92,"rain":7.75}]}'
Local $objJson = Jsmn_Decode($Json1)

Local $List = Jsmn_ObjGet($objJson, "list") ; "list" is an array
Local $objJson2 = $List[0]
Local $Temp = Jsmn_ObjGet($objJson2, "temp") ; "temp" is an object

ConsoleWrite(Jsmn_ObjGet($Temp, "day") & @LF)
ConsoleWrite(Jsmn_ObjGet($Temp, "min") & @LF)

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

 

Share this post


Link to post
Share on other sites

Hi Ward,

ahh ok now I understand: You have do know about the JSON structure and like an encapsulation take each part in an own list / array and at some point there is only a string left which can be queried for or values.

Before I thought that I can just query the whole JSON object and the function will give me the value in return. Is this also in other programming languages a common behaviour to "encapsulate" the whole JSON object or maybe is there a way to query the whole object for the needed string?

Anyway: Thanks for your very fast and efficient help :thumbsup: !

Regards

mmscripting

Share this post


Link to post
Share on other sites

Funny that I need such a UDF now. This has to be the best JSON UDF I've seen floating around the Forums. Thanks ward.


UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites

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

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

 

Share this post


Link to post
Share on other sites

I'm trying to parse the data below,

{"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"}]}

The end result would be an array with 3 columns for map_id, event_id, and state filled with the relevant data.

By striping '{"events":[' and ']}' from either end i managed to get the values of the first line/object but how do extract further items? I can't work out how to loop into the next line(s).

Thanks for any help. My code isn't really worth showing hence no code example.

 

Share this post


Link to post
Share on other sites

Using Jsmn_Get(), it's easy.

I will put this function into the UDF later.

#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"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][0]["map_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][0]["event_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][0]["state"]') & @LF)

ConsoleWrite(Jsmn_Get($Obj, '["events"][1]["world_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][1]["map_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][1]["event_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][1]["state"]') & @LF)

ConsoleWrite(Jsmn_Get($Obj, '["events"][2]["world_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][2]["map_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][2]["event_id"]') & @LF)
ConsoleWrite(Jsmn_Get($Obj, '["events"][2]["state"]') & @LF)

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

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

 

Share this post


Link to post
Share on other sites

Thanks! Wow, it's easy to do once you know the correct syntax. Thanks again for the UDF and your code above really helps me understand it more now :)

Edited by Fly By Night

Share this post


Link to post
Share on other sites

Perfect, right at the time i thought of buying the $400 n/Software json Activex the native and free udf comes around, thank you very much.


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites

I'm searching through a long (>800) list looking for a specific value using the following code and my routine seems to be very slow compared to using a similar version just using _StringBetween on the raw JSON string.

I'm not sure if i can reduce the number of Jsmn_Get calls using the logic below. Is the While..Wend method below one to use or am i missing a better way to hunt for a value. Thanks again.

Func getEventstate($eventID)


; Search for a specific EventID and return it's state


Local $evState = "", $evFound = 0
Local $i = 0

    While ((Jsmn_Get($EventsObj, '["events"][' & $i & ']["event_id"]') <> "") And $evFound = 0)

        If Jsmn_Get($EventsObj, '["events"][' & $i & ']["event_id"]') == $eventID Then
            $evState = Jsmn_Get($EventsObj, '["events"][' & $i & ']["state"]')
            $evFound = 1
        EndIf

        $i = $i + 1
    WEnd

    Return ($evState)
EndFunc   ;==>getEventstate2

For reference, same using _StringBetween

Func getEventstate($eventID)

    $srcStr = '"event_id":"' & $eventID & '","state":"'
    $evState = _StringBetween($EventsJson, $srcStr, '"}')

    If $evState <> "" Then
        Return ($evState[0])
    EndIf
EndFunc   ;==>getEventstate

Share this post


Link to post
Share on other sites

You can optimize this code (and maybe any code) to avoid do the same thing everytime in the loop. For example, you can get '["events"]' object and reuse it in the loop. And then you can aslo try to modify the code to get "[' & $i & ']" only once when the $i was changed.

However, even you wrote the optimized code, I don't think it will run faster than _StringBetween. So don't try to compare with that. 


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

 

Share this post


Link to post
Share on other sites

If I wanted to load in the Events object and search through all the values of a key for a specific one, what method would you recommend? I wasn't sure how to do this optimally that is why i ended up just doing a While..Wend using the $i to increment onto the next key until i find the value i'm after. Also i wasn't sure if   '["events"][' & $i & ']["event_id"]') <> "" was the correct method to check for end of keys. I realise what i'm after is a Jsmn_Search function that looks for a value and returns how to obtain it via Jsmn_Get.

I did a test of copying key values into an array using Jsmn_Get then _StringBetween and Jsmn_Get was a lot faster on a test of about 1600 keys.

Edited by Fly By Night

Share this post


Link to post
Share on other sites

Here is the JSMN_Get function that Ward wrote in post #12 written to allow both delimiter notation (dot, comma, pipe, whatever notation) and JSON notation.

; #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 santaryan

Share this post


Link to post
Share on other sites

Hello,

thanks for this UDF, it has been really helpful so far. However, I got one JSON string that seems impossible to decode with this UDF (I validated it with a JSON validator, so does not seem to be invalid):

I doesn't work in this form:

#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")
    For $i = 0 To UBound($auctions)-1
        Local $objJson2 = $auctions[$i]
        ConsoleWrite(Jsmn_ObjGet($objJson2, "p"))
    Next
EndIf

When I transform the JSON string like this, it produces an output:

#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}'

;JSMN compatibility
$JSON=StringRegExpReplace($JSON,'"\d{9}":','')
$JSON=StringReplace($JSON,'{"a":{','{"a":[')
$JSON=StringReplace($JSON,'}},','}],')

;produces
;$JSON='{"a":[{"v":673,"p":4.91,"lb":"test1","av":58,"sl":11.6},{"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")
    For $i = 0 To UBound($auctions)-1
        Local $objJson2 = $auctions[$i]
        ConsoleWrite(Jsmn_ObjGet($objJson2, "p"))
    Next
EndIf

What am I doing wrong ? Is it possible to get the auction details (like "p" in this example) without transforming the JSON string ?

Edited by level20peon

Share this post


Link to post
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

  • Similar Content

    • By D2thunder
      Hi all, I wasnt active in this Forum forum for Years. 😅
      Since I need something with Json in AutoIt i write a little UDF to save a variable to file to read it with another language - and back. After a while until my other script grows i thought - lets integrate all variables wich is possible, because i want have arrays to.
      This is my first public UDF in Autoit - normaly my AutoIt scripts are quick an dirty.... - like the examples for this udf. - someone want to write nice examples?
      I tried to write this UDF properly, cared for processing speed, low mem consumption as possible, a short code, and a high usability without beeing very familiar with arrays.
      What is it for? - convert nearly all types of variables to a json string for saving it in a file or to an ini. Read it back in to a same formated variable and preserv variable types. All array types are supported with nested arrays, the only restriction is ram and array/stringsize - and time if the array is very big. You can use Filters for variable types and some other options.
      If anyone found a bug or any suggestions, please post it.
       
      get Json.au3 from here Json.au3
       
       
      JsonVar 2019.01.25.1.zip
    • By JoeBar
      Hi, i'm trying to implement Imgur API functions in an AutoIt program.
      I successfully coded the oAuth2 Authentication and i'm testing some Imgur functions.
       
      Example : https://api.imgur.com/3/account/me/images
      The string received is like :
      {"data":[{"id":"fd6f54s","title":null,"description":null,"datetime":1574502473,"type":"image\/png","animated":false,"width":1147,"height":715,"size":53516,"views":18,"bandwidth":963288,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":"ACCOUNT","account_id":ACCOUNTID,"is_ad":false,"in_most_viral":false,"has_sound":false,"tags":[],"ad_type":0,"ad_url":"","edited":"0","in_gallery":false,"deletehash":"d6f5sd4fsf","name":"image","link":"https:\/\/i.imgur.com\/fd6f54s.png"} I'm using JSON.au3 UDF and i don't manage to make it working :
      Local $Obj = Json_Decode($hRequestSSL) Local $Links = Json_Get($Obj, '["data"]["link"]') The Json_Decode sends in console :
      "E:\Portable\Dev\AutoIt3\IncludeP\JSON.au3" (374) : ==> Variable must be of type "Object".: Return $Object.Keys() Return $Object^ ERROR It says it's not an object or i have seen in some UDF that Json_Decode takes a string as parameter.
      I don't know what's wrong.
    • By uncommon
      So I have been reading on how to use OAuth2 Service accounts(https://developers.google.com/identity/protocols/OAuth2ServiceAccount) and ran into an issue with autoit I can not solve. To keep this short to communicate to the Google API I need to use a JSON Web signature containing
      {Base64url encoded header}.{Base64url encoded claim set}.

      The Header and claim set work fine but I do not know how to convert them to a byte array using autoit. I have looked around on the forums and website but have not found anything that seems to work. Here is my code.
      #include-once #include <Array.au3> #include <Constants.au3> #include <Debug.au3> #include <File.au3> #include "Json.au3" #include <Process.au3> #include <ProgressConstants.au3> #include <String.au3> #include <WindowsConstants.au3> #include "WinHttp.au3" #include <UnixTime.au3> #include <StringConstants.au3> Global $UnixTime = _TimeGetStamp() $sJWTheader = '{"alg":"RS256","typ":"JWT"}' $sJWTclaimset = '{"iss":"Removed@forprivacy.com","scope":"https://www.googleapis.com/auth/spreadsheets","aud":"https://www.googleapis.com/oauth2/v4/token","exp":' & $UnixTime + 3600 & ',"iat":' & $UnixTime & '}' Local $taiData = DllStructCreate("BYTE[256]") Local $sText = _base64($sJWTheader)&'.'&_base64($sJWTclaimset) DllStructSetData($taiData, 1, StringToBinary($sText, 4)) Local $bvResult = DllStructGetData($taiData, 1) $sJWTSigature = $bvResult $sJWT = _base64($sJWTheader)&'.'&_base64($sJWTclaimset)&'.'&_base64($sJWTSigature) $POSTHeader = "Content-Type: application/x-www-form-urlencoded" $hOpen = _WinHttpOpen() $hConnect = _WinHttpConnect($hOpen, "https://www.googleapis.com/") $sRead = _WinHttpSimpleSSLRequest($hConnect, "POST", "oauth2/v4/token", Default, "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" & $sJWT) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) ConsoleWrite($sRead & @LF) The whole bytes thing is beyond with what I know about auotit. I can't tell what I need to fix.
       
       
    • By Miliardsto
      You can see my script to POST json and the problem where occurs backslashes before quotations. Second problem is the apperance , there is no new lines for every new value.
      LOOK in attached images!
       
      You can see rest api on the screen and with id = 0 its made my postman and the rest by autoit (with backslashes)
       
      Func jsonSave() ; Make login request to server JSON POST Local $data, $request Local $obj Local $adress = 'http://35.195.249.40:3004/msg' Json_Put($Obj, ".msgName", "Point HPs") Json_Put($Obj, ".msg", "Not pointed correctly") Json_Put($Obj, ".username", "karolek890") Local $Json = Json_Encode($Obj,$JSON_UNESCAPED_SLASHES) ; WITHOUT preetier becouse it makes clashes r n and t only works in autoit $request = _httpRequestBot($adress, 'POST', $Json) ; only get login if correct then success If @error Then Exit MsgBox(0, "Error", "Open method returned @error = " & @error & " and @extended = " & @extended) Else ConsoleWrite("Data to json server posted!") EndIf EndFunc  
      Im using this JSON UDF
       
       
       


    • By jchd
      Here's a new version of my Dump.au3 file (dirty). I've recently added support to dissect (dump) as a treeview-like view any string in the variable conforming to a strict JSON grammar, whereever said string is: as a standalone string variable or in an array or a map. AFAICT the only relaxed constraint not implemented here is that numbers in parsed JSON may have leading zeroes, although leading zeroes are forbidden in pure JSON specifications. If required it wouldn't be hard to add this constraint.
      @c.haslam (among others) may find it useful. Use freely.
      Dump.au3
×
×
  • Create New...