Ward Posted November 3, 2013 Author Posted November 3, 2013 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 level20peon 1 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。
level20peon Posted November 14, 2013 Posted November 14, 2013 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 ?
Siahtech Posted January 23, 2014 Posted January 23, 2014 (edited) 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: expandcollapse popup#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 January 23, 2014 by Siahtech
this-is-me Posted February 13, 2014 Posted February 13, 2014 (edited) 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? expandcollapse popup#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 February 13, 2014 by this-is-me Who else would I be?
this-is-me Posted February 15, 2014 Posted February 15, 2014 (edited) 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 February 15, 2014 by this-is-me Who else would I be?
TechCoder Posted March 21, 2014 Posted March 21, 2014 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? expandcollapse popup#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
TechCoder Posted March 21, 2014 Posted March 21, 2014 found it! "name":"" the UDF doesn't like the empty string - it wants ==>null<== or some with-character(s) string. So, the 'fix' - I did a quick StringReplace...... $string2test = StringReplace($string2test,'""','null') puts everything back in place.
lxxl Posted March 25, 2014 Posted March 25, 2014 (edited) Guys, i can't get this magic ... here is my JSON array expandcollapse popup[ { "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 any help ? thxx Edited March 25, 2014 by lxxl
TechCoder Posted March 25, 2014 Posted March 25, 2014 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?
lxxl Posted March 25, 2014 Posted March 25, 2014 Many thx for fast reply TechCoder, good explanation and way to eat it, after add $resault = Jsmn_Get($Obj1, '[0]') i in console popup only @CRLF) so maybe the _filetoarray fail dunno
TechCoder Posted March 25, 2014 Posted March 25, 2014 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'... ) Skysnake 1
lxxl Posted March 26, 2014 Posted March 26, 2014 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: expandcollapse popup; #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 ?
TechCoder Posted March 26, 2014 Posted March 26, 2014 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.
tes5884 Posted July 29, 2014 Posted July 29, 2014 (edited) 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 July 29, 2014 by tes5884 www.tspitz.com
Ward Posted July 30, 2014 Author Posted July 30, 2014 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 的白痴作者,不管是誰,去死一死好了。
tes5884 Posted July 30, 2014 Posted July 30, 2014 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! www.tspitz.com
poolcat Posted September 4, 2014 Posted September 4, 2014 (edited) 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 expandcollapse popup#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 September 4, 2014 by poolcat Gianni 1
Ward Posted January 8, 2015 Author Posted January 8, 2015 == 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 的白痴作者,不管是誰,去死一死好了。
argumentum Posted January 21, 2015 Posted January 21, 2015 (edited) 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. expandcollapse popup#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 January 21, 2015 by argumentum Gianni 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
mojomatt Posted February 3, 2015 Posted February 3, 2015 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now