Ward Posted February 3, 2015 Author Posted February 3, 2015 #Include "Json.au3" Local $Json = '{ "Headers":[ { "Name":"LOGICAL_NAME","Type":"VARCHAR2"}],"ColumnCount":1,"Rows":[ { "Cells":[ "ThisIsWhatIWant"],"CellCount":1}]}' Local $Obj = Json_Decode($Json) ConsoleWrite(Json_Get($Obj, '["Rows"][0]["Cells"][0]') & @LF) ConsoleWrite(Json_Get($Obj, '.Rows[0].Cells[0]') & @LF) ConsoleWrite(Json_Encode($Obj, $JSON_PRETTY_PRINT) & @LF) argumentum 1 新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了。
mojomatt Posted February 3, 2015 Posted February 3, 2015 Wow, for such a short script that's pretty complicated - but I get it now. Thanks for your timely help Argumentum!
mojomatt Posted February 3, 2015 Posted February 3, 2015 Thanks Ward - I didn't realize I was using json_ObjGet instead of json_Get. Makes quite a bit of difference. Slick and easy!
argumentum Posted February 3, 2015 Posted February 3, 2015 Wow, for such a short script that's pretty complicated - but I get it now. Thanks for your timely help Argumentum! thanks, Ward's is the correct one, therefore I removed my answer to not confuse anyone in the future. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted February 8, 2015 Posted February 8, 2015 (edited) I'm learning JSON, so I wanted a ConsoleWriteJson( $StringJson ) , so I put it together, it may help the next guy ( you'd need to #include <JSON.au3> , but you know that. ) Edit1: I see I did not code anything in case of error. expandcollapse popupFunc ConsoleWriteJson($sJsonString, $sDesc = "", $iEcho = True) If $sDesc = "" Then $sDesc = 'ConsoleWriteJson' Local $obj = Json_Decode($sJsonString) Local $sOutGlobal = "" Return Json_Iterate($obj, '', $sOutGlobal, $sDesc, $iEcho) EndFunc ;==>ConsoleWriteJson Func Json_Iterate($obj, $String, ByRef $sOutGlobal, $pre = "", $iEcho = True) Local $sOut = "" Local $temp, $i, $b If ($pre <> "") Then $sOutGlobal &= $pre & ": " If $iEcho Then ConsoleWrite($pre & ": ") EndIf $a = Json_Get_ShowResult($obj, $String, $sOutGlobal, $iEcho) If IsArray($a) Then For $i = 0 To UBound($a) - 1 Json_Iterate($obj, $String & '[' & $i & ']', $sOutGlobal, $pre, $iEcho) Next ElseIf IsObj($a) Then $b = Json_ObjGetKeys($a) For $temp In $b Json_Iterate($obj, $String & '["' & $temp & '"]', $sOutGlobal, $pre, $iEcho) Next EndIf Return $sOutGlobal EndFunc ;==>Json_Iterate Func Json_Get_ShowResult($Var, $Key, ByRef $sOutGlobal, $iEcho) Local $sOut = "" Local $Ret = Json_Getr($Var, $Key) If @error Then Switch @error Case 1 $sOut &= "Error 1: key not exists" & @LF $sOutGlobal &= $sOut If $iEcho Then ConsoleWrite($sOut) Case 2 $sOut &= "Error 2: syntax error" & @LF $sOutGlobal &= $sOut If $iEcho Then ConsoleWrite($sOut) EndSwitch Else $sOut &= $Key & " => " & VarGetType($Ret) & ": " & $Ret & @LF $sOutGlobal &= $sOut If $iEcho Then ConsoleWrite($sOut) 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 Edited February 8, 2015 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
FaridAgl Posted May 20, 2015 Posted May 20, 2015 (edited) @WardI just come to say "Thank you so much" for this great UDF.I'm using it for a while, saved my ass multiple times and I just felt I have to say "Thanks".Thank you. Edited May 20, 2015 by FaridAgl http://faridaghili.ir
Jemboy Posted June 7, 2015 Posted June 7, 2015 Thank you Ward for the time invested in this UDF, because I really do not understand the whole JSON thing yet , so I am thankfull you do ;-)I wanted to change some settings in the Chrome preferences-file, which turnout to be a JSON-file, so I am going to use your UDF!
Xplode Posted August 30, 2015 Posted August 30, 2015 (edited) Hello,It seems that having ExpandVarStrings or ExpandEnvStrings option set to 1 makes Json_encode() function crashes. I have to do this in order to make the function works : Opt("ExpandVarStrings",0) Opt("ExpandEnvStrings",0) Json_Encode($obj,$JSON_UNESCAPED_SLASHES)) Opt("ExpandVarStrings",1) Opt("ExpandEnvStrings",1)Otherwise the program simply crashes ( There is no AutoIT error, the program just crashes ). Are you aware of this possible bug ?Regards. Edited August 30, 2015 by Xplode
kyo Posted November 20, 2015 Posted November 20, 2015 Ahh... working with JSON is so much easier tolerable now, thanks to you Ward!I'm so glad I found this UDF!!
AdamUL Posted December 11, 2015 Posted December 11, 2015 The UDF is unavailable for download, and is not listed in Downloads. Does any one know where I can get it? Thanks,Adam
argumentum Posted December 11, 2015 Posted December 11, 2015 The UDF is unavailable for download, and is not listed in Downloads. ...here until fixed or a reason for not been there Gianni 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
AdamUL Posted December 11, 2015 Posted December 11, 2015 argumentum, Thanks for uploading it. Adam argumentum 1
Jury Posted December 14, 2015 Posted December 14, 2015 (edited) How do I list the last level of objects in the last level of keys? As you can see I've commented out my last, of many, efforts. #include "Json.au3" $Json = '{"Air Elemental":{"layout":"normal","name":"Air Elemental","manaCost":"{3}{U}{U}","cmc":5,"colors":["Blue"],"type":"Creature — Elemental","types":["Creature"],"subtypes":["Elemental"],"text":"Flying","power":"4","toughness":"4","imageName":"air elemental","colorIdentity":["U"]},"Ancestral Recall":{"layout":"normal","name":"Ancestral Recall","manaCost":"{U}","cmc":1,"colors":["Blue"],"type":"Instant","types":["Instant"],"text":"Target player draws three cards.","imageName":"ancestral recall","colorIdentity":["U"]}' $Obj = Json_Decode($Json) If Json_IsObject($Obj) Then $Keys = Json_ObjGetKeys($Obj) For $i = 0 To UBound($Keys) - 1 ConsoleWrite($Keys[$i] & @LF) $obects = Json_ObjGet($Obj, $Keys[$i]) $KeysB = Json_ObjGetKeys($obects) For $h = 0 To UBound($KeysB) - 1 ConsoleWrite(' ' & $KeysB[$h] & @LF) ;~ $obectsB = Json_ObjGet($obects, $KeysB[$h]) ;~ $KeysC = Json_ObjGetKeys($obectsB) ;~ For $g = 0 To UBound($KeysC) - 1 ;~ ConsoleWrite(' ' & $KeysC[$g] & @LF) ;~ Next Next Next EndIf Edited December 14, 2015 by Jury
argumentum Posted December 14, 2015 Posted December 14, 2015 (edited) How do I list the last level of objects in the last level of keys?according to http://stackoverflow.com/questions/4317456/getting-the-last-item-in-a-javascript-objectNo. Order is not guaranteed in JSON and most other key-value data structures, so therefore the last item could sometimes be carrot and at other times be banana and so on. If you need to rely on ordering, your best bet is to go with arrays. The power of key-value data structures lies in accessing values by their keys, not in being able to get the nth item of the object.or play around with ConsoleWriteJson https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/?do=findComment&comment=1224189 aboveEdit: I see that the string has game like values and if it's a bot, I just got me in trouble for helping, but you've been here since 2009 and would not even dream of that. Edited December 14, 2015 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Jury Posted December 15, 2015 Posted December 15, 2015 Thanks - I'm not interested in the string - I just got it off the internet as an example of jsonhttp://mtgjson.com/silly me I didn't even think of what it was. Sorry everyone. argumentum 1
Tipulatoid Posted December 19, 2015 Posted December 19, 2015 Hello.I wonder if there is a quick way to get key knowing only the array element.Here is JSON string:{"result":{"tree":{"36":{"1958":[989,1649,2066,659,616]},"4":{"2317":[886,2350,2219,1520,795,1352,809,2521],"1960":[2197,1628,1538,2332,1416],"489":[1277],"1289":[2213,25,2105,2214]},"34":{"2354":[1271],"2362":[1265,1266,1267,1358,2363,1268,1673,1269,1270,1275,2364,1276,1274],"1264":[2358,2359,2360,2361],"2057":[2355,2474,2356,2357],"2413":[1501,1580,525]},"10":{"610":[628,1568,1542,2335,1544,1545,1546,1549,1597,1552,1550,1553,1554,617,1555,2017,1257,1258,2208,677,1255,1479,1261,614,1259,2065,1254,1260,2209,2210,1547,1548,2211,615],"1581":[1582,1583,1590,1587,1594,1591,1588,1596,1585,1586,2078,1929,1593,1592,1595],"1556":[1557,1560,1561,1653,1570,1654,1655,1656,1930,1931,1932,1562,1563,1626,1564,1565,1559,1566,1573,1567]},"33":{"395":[396,2322,2167,1993,2321],"2326":[1036,400,574],"2389":[2387,2388],"2327":[695,399,402,490,499],"2324":[2325,2342,530,2152],"2328":[403,1279,716,2165,401]}}}}I know only array element, for example, 1583. I need to get key - 10Here is how I do that for now:#Include <Array.au3> #Include <Json.au3> ; https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/ $iForumID = 1583 $sJSON = '{"result":{"tree":{"36":{"1958":[989,1649,2066,659,616]},"4":{"2317":[886,2350,2219,1520,795,1352,809,2521],"1960":[2197,1628,1538,2332,1416],"489":[1277],"1289":[2213,25,2105,2214]},"34":{"2354":[1271],"2362":[1265,1266,1267,1358,2363,1268,1673,1269,1270,1275,2364,1276,1274],"1264":[2358,2359,2360,2361],"2057":[2355,2474,2356,2357],"2413":[1501,1580,525]},"10":{"610":[628,1568,1542,2335,1544,1545,1546,1549,1597,1552,1550,1553,1554,617,1555,2017,1257,1258,2208,677,1255,1479,1261,614,1259,2065,1254,1260,2209,2210,1547,1548,2211,615],"1581":[1582,1583,1590,1587,1594,1591,1588,1596,1585,1586,2078,1929,1593,1592,1595],"1556":[1557,1560,1561,1653,1570,1654,1655,1656,1930,1931,1932,1562,1563,1626,1564,1565,1559,1566,1573,1567]},"33":{"395":[396,2322,2167,1993,2321],"2326":[1036,400,574],"2389":[2387,2388],"2327":[695,399,402,490,499],"2324":[2325,2342,530,2152],"2328":[403,1279,716,2165,401]}}}}' ConsoleWrite (_GetAPICategoryID ($iForumID) & @CRLF) Func _GetAPICategoryID ($iffAPIForumID) $Obj = Json_ObjGet(Json_ObjGet(Json_Decode($sJSON), "result"), "tree") $aTMP15 = Json_ObjGetKeys ($Obj) $iFoundCategoryID = "" For $i = 0 To UBound ($aTMP15) -1 $Obj1 = Json_ObjGet ($Obj, $aTMP15[$i]) $aTMP16 = Json_ObjGetKeys ($Obj1) For $x = 0 To UBound ($aTMP16) -1 $aTMP17 = Json_Get ($Obj1, '["' & $atmp16[$x] & '"]') If _ArraySearch ($aTMP17, $iffAPIForumID) <> -1 Then $iFoundCategoryID = $aTMP15[$i] ExitLoop EndIf Next If $iFoundCategoryID <> "" Then ExitLoop Next Return $iFoundCategoryID EndFunc ; _GetAPICategoryID ()But this is too slow and not gracefully. Maybe there is better way? Thank you in advance
addjon Posted January 17, 2016 Posted January 17, 2016 Hello. I want to say thank you for this UDF, I tried other, nothing worked. And this figured out thanks to the topic and running. But still faced with the problem and do not know how to do that. I hope will prompt Have two json json_1 {"response":{"status":1,"httpStatus":200,"data":[{"id":"10445","categories":{"6":{"id":"6","name":"D"},"27":{"id":"27","name":"I"}}},{"id":"10159","categories":{"20":{"id":"20","name":"W"}}}],"errors":[],"errorMessage":null}} json_2 {"response":{"status":1,"httpStatus":200,"data":[{"id":"11930","countries":{"CH":{"id":"756","code":"CH","name":"Switzerland","regions":[]}}},{"id":"11928","countries":{"UK":{"id":"826","code":"UK","name":"United Kingdom","regions":[]},"HR":{"id":"191","code":"HR","name":"Croatia","regions":[]}}}],"errors":[],"errorMessage":null}} from both must be received "name" in the first "categories", the second of the "countries" my code #include <Array.au3> #include "JSON.au3" $sJSON = FileRead(@ScriptDir & "\1.json") $objJson = Json_Decode($sJSON) $Response = Json_ObjGet($objJson, "response") $Data = Json_ObjGet($Response, "data") Local $N = UBound($Data) Dim $List[$N] For $i = 0 To UBound($Data) - 1 Local $objJson2 = $Data[$i] Local $Categories = Json_ObjGet($objJson2, "categories") ;or "countries" for json_2 Local $nCat = Json_ObjGetKeys($Categories) Local $N = UBound($nCat) Dim $aCat[$N] For $j = 0 To UBound($nCat) - 1 Local $objJson2 = Json_ObjGet($Categories, $nCat[$j]) $aCat[$j] = Json_ObjGet($objJson2, "name") Next $strCat = '' For $j = 0 to UBound($aCat) - 1 $strCat &= $aCat[$j] & ', ' Next $strCat = StringTrimRight($strCat, 2) $List[$i] = $strCat Next _ArrayDisplay($List,"List") For json_1 works fine. For json_2 function Json_ObjGetKeys an error JSON.au3 "(342): ==> Variable must be of type" Object ".: Return $ Object.Keys () Return $ Object ^ ERROR I realized that the reason for this error is that the structure of "countries" objects letters "CH", "UK" and the like, and the structure of the "categories" - number How do I get the data from "countries" in this situation?
argumentum Posted January 18, 2016 Posted January 18, 2016 @addjon, many ask for an Arrayfied Json. Here is my take at it, that works with your string. ( may not work with others ) expandcollapse popup#include <JSon.au3> #include <Array.au3> Local $sJson_1 = '{"response":{"status":1,"httpStatus":200,"data":[{"id":"10445","categories":{"6":{"id":"6","name":"D"},"27":{"id":"27","name":"I"}}},{"id":"10159","categories":{"20":{"id":"20","name":"W"}}}],"errors":[],"errorMessage":null}}' Local $sJson_2 = '{"response":{"status":1,"httpStatus":200,"data":[{"id":"11930","countries":{"CH":{"id":"756","code":"CH","name":"Switzerland","regions":[]}}},{"id":"11928","countries":{"UK":{"id":"826","code":"UK","name":"United Kingdom","regions":[]},"HR":{"id":"191","code":"HR","name":"Croatia","regions":[]}}}],"errors":[],"errorMessage":null}}' Local $aReturned = JsonArrayfied($sJson_1) _ArrayDisplay($aReturned, "$aReturned") $aReturned = JsonArrayfied($sJson_2) _ArrayDisplay($aReturned, "$aReturned") Func JsonArrayfied($sJsonString, $iEcho = 0) Local $sConsoleWriteJson = ConsoleWriteJson($sJsonString, "", $iEcho) Local $n, $aLines = StringSplit($sConsoleWriteJson, @LF, 1) Local $aTemp, $iRow = 0, $iCol = 0, $m, $aJsonArrayfied[UBound($aLines) + 1][100] ; a lazy but efficient way to go about it For $n = 1 To $aLines[0] If StringInStr($aLines[$n], ":") + 2 > StringLen($aLines[$n]) Then ContinueLoop $aLines[$n] = StringReplace($aLines[$n], "][", "|") $aLines[$n] = StringReplace($aLines[$n], "]", "|") $aLines[$n] = StringReplace($aLines[$n], "[", "|") $aTemp = StringSplit($aLines[$n], "|") $iRow += 1 For $m = 1 To $aTemp[0] - 1 If $iCol < $m Then $iCol = $m $aJsonArrayfied[$iRow][$m - 1] = StringReplace($aTemp[$m], '"', '') Next $aJsonArrayfied[$iRow][$aTemp[0] - 1] = StringTrimLeft($aTemp[$aTemp[0]], StringInStr($aTemp[$aTemp[0]], ":") + 1) $aJsonArrayfied[$iRow][0] = StringMid($aTemp[$aTemp[0]], 5, StringInStr($aTemp[$aTemp[0]], ":") - 5) Next $aJsonArrayfied[0][0] = $iRow $aJsonArrayfied[0][1] = $iCol ReDim $aJsonArrayfied[$iRow + 1][$iCol + 1] Return $aJsonArrayfied EndFunc ;==>JsonArrayfied ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; added by me Func ConsoleWriteJson($sJsonString, $sDesc = "", $iEcho = 1) Local $sOutGlobal If $sDesc = "" Then $sDesc = 'ConsoleWriteJson' Local $obj = Json_Decode($sJsonString) Json_Iterate($sOutGlobal, $obj, '', $sDesc, $iEcho) Return $sOutGlobal EndFunc ;==>ConsoleWriteJson Func Json_Iterate(ByRef $sOutGlobal, $obj, $string, $pre = "", $iEcho = 1) Local $sOut = "" Local $temp, $i, $b If ($pre <> "") Then $sOut &= $pre & ": " If $iEcho Then ConsoleWrite($pre & ": ") EndIf $a = Json_Get_ShowResult($obj, $string, $sOutGlobal, $iEcho) If IsArray($a) Then For $i = 0 To UBound($a) - 1 Json_Iterate($sOutGlobal, $obj, $string & '[' & $i & ']', $pre, $iEcho) Next ElseIf IsObj($a) Then $b = Json_ObjGetKeys($a) For $temp In $b Json_Iterate($sOutGlobal, $obj, $string & '["' & $temp & '"]', $pre, $iEcho) Next EndIf Return $sOutGlobal EndFunc ;==>Json_Iterate Func Json_Get_ShowResult($Var, $Key, ByRef $sOutGlobal, $iEcho) Local $sOut = "" Local $Ret = Json_Getr($Var, $Key) If @error Then Switch @error Case 1 $sOut &= "Error 1: key not exists" & @LF If $iEcho Then ConsoleWrite($sOut) Case 2 $sOut &= "Error 2: syntax error" & @LF If $iEcho Then ConsoleWrite($sOut) EndSwitch Else $sOut &= $Key & " => " & VarGetType($Ret) & ": " & $Ret & @LF If $iEcho Then ConsoleWrite($sOut) EndIf $sOutGlobal &= $sOut ;& $Ret 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 Hope it helps to get what you look for. addjon and JoeBar 2 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Jury Posted January 24, 2016 Posted January 24, 2016 argumentum, Brilliant! and here I was attempting to stuff json into an array with little success. Attached is an example of my data - it takes some time but then the end is an array of over 20,000 lines. So much better and reliable than parsing using regular expressions etc. Thanks ever so... cma-cases.json argumentum 1
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