ozmike Posted December 6, 2013 Share Posted December 6, 2013 (edited) Hi This UDF is for anyone who- Object Orientated Programing ie properties and methods in autoIT- needs standards compliant JSON,, - JSON.parse (read) and JSON.stringify (to text )- Now JSONPath- wants to use dot syntax in AutoIT like you would in Javascript - dosen't like AutoIt arrays - full javascript arrays and objects in AutoIT! - knows javascript or would like to learn autoIT or vice versa.- call javascript functions like EncodeURI- run any javascript from autoIT ! Tested IE8 - IE11. v7 JSON_OO v7.zip - IE free version. ( hey microsoft ditched IE now too!) .- No IE dependencies- Added arrayAdd and arrayDel- JSONPath! for searching.- Added Keys Function - to list properties of a JSON object.- Secure JSON parse- Native Pure JS implementaion not a port.Credits to Douglas Crockford's for JSON2 code and stefan.goessner for JSONPath code.(see example file). v4 - json_oo_v4.zip. - use v7 (v4 may not work because of windows updates on dec-2014. ).v4 uses IEs JSON , so no ported external librariesv4 also includes a Non - IE version of JSON no include files but no stringify and uses javascript EVal (not secure). use v7.eg valid JSON '{ "hello" : "world" }' invalid "{ 'hello' : 'world' }"v4 does not have JSONPath , arrayAdd, arrayDel or keys (properties) methods - use v7 - enjoy...the brakes come off Autoit . This is the smallest OO extensions for AutoITObject Oriented JSON --- using JSON to Build Objects in Native AutoIT -- Using JSON to create objects $oJSON = _OO_JSON_Init ( ) $jsObj = $oJSON.parse('{ "hello": "world" }') $jsObj.hello;-> world $oJSON.stringify( $jsObj );-> {"hello":"world"} $jsObj.stringify();-> {"hello":"world"} ARRAYS - goodbye Auto it arrays hoorayThe real magic in this script is that it lets you access JSON array items by index number through dot syntaxwithout the need for a for-each loop. eg you can go $obj.arr.item(n) It does this by making javascript objects syntax friendly to Autoit.. Also you can go $obj.arr.item("property").and $obj.arr.property & Also $obj.arr.length (see below) -- Using JSON to create one dimentional array $sJSON=[ "h1", "h2", "h3" ] $oResult.length= 3 $oResult.item(0);-> h1 -- Using JSON to create 2 dimentional array; $sJSON=[[1,2],[3,4],[5,6]] $oResult.length= 3 $oResult.item(0);-> $oResult.item(0).stringify();-> [1,2] $oResult.item(2).item(1);-> 6 $oResult.item(2).length;-> 2 -- Using JSON to create an object array $sJSON= [ { "card":"ace" }, {"card":"king" }] $oResult.length= 2 $oResult.item(0).card;-> ace -- Using JSON to create key values $sJSON= { "name":"Jon" , "surname":"who" } $oResult.item("surname");-> who $oResult.surname ;-> who Many other benefits such as building objects using JSON text just like you would in JavaScript Basic OO - Properties and methods-- Add properties to objects in AutoIT $jsObj.propAdd("myProp", "'x'") $jsObj.myProp ;-> x $jsObj.propAdd("myProp", '{ "hello": "world" }') $jsObj.myProp.hello ;-> world -- User Defined methods - using javascript -CASE SENSITIVE $jsObj.methAdd("myMethod", " Function('y','return y*5') " ) $jsObj.myMethod(5) ;-> 25 Some people have problems on 64 bit autoIT windows with the script control...here is the work around..'?do=embed' frameborder='0' data-embedContent>>You will most likely have the script control ..but here it is.. http://www.microsoft.com/en-us/download/details.aspx?id=1949 expandcollapse popup--- using JSON to Build Objects in Native AutoIT -- Using JSON to create objects $oJSON = _OO_JSON_Init ( ) $jsObj = $oJSON.parse('{ "hello": "world" }') -- Accessing Items $jsObj.hello;-> world $jsObj.item("hello");-> world -- Using Any Object to create objects $jsObj.stringify();-> {"hello":"world"} $jsObj = $jsObj.parse('{ "goodbye": "world" }') $jsObj.goodbye;-> world -- Read JSON from a file (PC only) - untested $var = _OO_JSON_Read_File("jsondata.txt") $obj = $oJSON.parse($var) > BASIC OO (Object Oriented) programming in Auto it -- Compound Syntax $oJSON.parse( '{ "hello":"world" }' ).hello;-> world -- assigning propeprties $jsObj.parse ( '{ "goodbye": "world" }') $jsObj.goodbye ;-> world $jsObj.goodbye = "hello" $jsObj.goodbye;-> hello > OO Adding Methods and Properties in Auto it -- Add properties to objects in AutoIT $jsObj.propAdd("myProp", "'x'") $jsObj.myProp ;-> x $jsObj.propAdd("myProp", '{ "hello": "world" }') $jsObj.myProp.hello ;-> world -- User Defined methods - using javascript -CASE SENSITIVE $jsObj.methAdd("myMethod", " Function('y','return y*5') " ) $jsObj.myMethod(5) ;-> 25 > Querying Objects $jsObj = $oJSON.parse('{ "hello": "world" , "Goodbye" : "World" } ') $jsObj.type($jsObj) ->object $jsObj.isArray() ->False -- List object properties or "keys" $jsObj.keys($jsObj).stringify() ->["hello","Goodbye"] -- Querying Objects $jsObj = $jsObj.parse({ "hello" : "world" , "myarray" : [ "item0", 2 , { "jon" : "who"} ] }) > JSON path - always returns an array of matches $jsObj.jsonPath( "$.*").stringify() -> ["world",["item0",2,{"jon":"who"}]] $jsObj.jsonPath( "$..hello").stringify() -> ["world"] $jsObj.jsonPath( "$..myarray").stringify() ->[["item0",2,{"jon":"who"}]] $jsObj.jsonPath( "$..myarray[?(@.jon)]").stringify() ->[{"jon":"who"}] $jsObj.jsonPath( "$..myarray[?(@.jon)]").item(0).stringify() ->{"jon":"who"} > Basic Arrays using JSON -- Querying Arrays $jsObj.myarray.stringify() ->["item0",2,{"jon":"who"}] $jsObj.type($jsObj.myarray) ->object $jsObj.myarray.isArray() ->True $jsObj.myarray.length ->3 $jsObj.type($jsObj.myarray.item(0)) ->string $jsObj.type($jsObj.myarray.item(1)) ->number $jsObj.type($jsObj.myarray.item(2)) ->object > Modifying Arrays using OO -- Empty array; $jsObj = $oJSON.parse('[]') $jsObj.stringify() ->[] $jsObj.isArray( ) ->True -- Add items; $jsObj.arrayAdd( 0, "test0") $jsObj.arrayAdd( 1, "test1") $jsObj2 = $oJSON.parse( '{ "hello" : "world" }') $jsObj.arrayAdd( 2, $jsObj2) $jsObj.stringify() ->["test0","test1",{"hello":"world"}] -- Delete items; $jsObj.arrayDel( 0) $jsObj.stringify() ->["test1",{"hello":"world"}] -- Using JSON to create one dimentional array $sJSON=[ "h1", "h2", "h3" ] $oResult.length= 3 $oResult.item(0);-> h1 -- Using JSON to create 2 dimentional array; $sJSON=[[1,2],[3,4],[5,6]] $oResult.length= 3 $oResult.item(0);-> $oResult.item(0).stringify();-> [1,2] $oResult.item(2).item(1);-> 6 $oResult.item(2).length;-> 2 -- Using JSON to create an object array $sJSON= [ { "card":"ace" }, {"card":"king" }] $oResult.length= 2 $oResult.item(0).card;-> ace -- Using JSON to create key values $sJSON= { "name":"Jon" , "surname":"who" } $oResult.item("surname");-> who $oResult.surname ;-> who > Working with OO Objects -- assigning JSON objects in AutoIT $jsObj = $oJSON.parse( '{ "hello" : "world" }') $jsObj2 = $oJSON.parse( '{}' ) $jsObj2 = $jsObj $jsObj.hello;-> world $jsObj2.hello;-> world -- Assign an JSON object to a property $jsObj = $oJSON.parse( '{ "hello" : "world" }') $jsObj.hello ;-> world $jsObj2.propAdd("myProp") $jsObj2.myProp = $jsObj $jsObj2.myProp ;-> $jsObj2.myProp.stringify() ;-> {"hello":"world"} $jsObj2.myProp.hello ;-> world -- Using Existing JS Objects , Object must exist in the scripting object (not IE) $oJSON2 =$jsObj.objGet('JSON') ; objGet is javascript eval $oResult = $oJSON2.parse('{ "hello":"world" }') $oResult.hello;-> world > Using Javascript functions extending UDF -- Calling javascript standard functions $jsObj.jsFunAdd( "encodeURI") $jsObj.encodeURI( 'te st' );-> te%20st $jsObj.protoAdd("encodeURI", " function (s) { return encodeURI(s); } " $jsObj.encodeURI( 'te st' );-> te%20st -- Calling javascript literal methods $str_obj = $jsObj.toObj("my string") $str_obj.jsMethAdd( "charAt") $str_obj.charAt( 0 );-> m $jsObj.toObj('\"my string').charAt(0) ;-> \ $str_obj.jsFunAdd( "charAt") $str_obj.charAt( 0 );-> m $jsObj.jsMethAdd("toFixed" ) $jsObj.toObj(5.56789).toFixed(2) ;-> 5.57 $jsObj.jsMethAdd("concat" , 3 ) $jsObj.toObj('hello').concat( ' world', ' again ', ' and again ' ) ;-> hello world again and again $jsObj.dot("\""'my string", "charAt(0)" );-> \ > depreciated syntax -- depreciated syntax - previous UDFs $jsObj = _JS_obj_create ( '{ "hello": "world" }') ; invalid "{ 'hello':'world'}" $jsObj.hello ;-> world $jsObj.objToString();-> {"hello":"world"} $jsObj.strToObject ( '{ "goodbye": "world" }') $jsObj.goodbye ;-> world -- Close IE explorer.exe instance - not required anymore _OO_JSON_Quit ( ) -- Objects still usable after _OO_JSON_Quit closes $jsObj.goodbye ;-> world Example script output; see example file; enjoy Edited May 29, 2015 by ozmike redrider81, mLipok, Jefrey and 1 other 4 Link to comment Share on other sites More sharing options...
ozmike Posted January 1, 2014 Author Share Posted January 1, 2014 (edited) Thx dwalf Sorry i didn;t get back to you, glad someone using my udf on christmas day! Silly mistake on my part - must have left a duplicate init call in during testing..it would start up 2 IEs - da! The new version should fix this issue - i also included the IEWait as you suggested..shouldn't hurt. On finding what the 'path' to an element - search GOOGLE for a online JSON viewer it should let you explore your JSON. I have now added JSOn path support.. cheers mike Edited February 2, 2015 by ozmike Link to comment Share on other sites More sharing options...
Voodooman Posted May 6, 2014 Share Posted May 6, 2014 Ozmike can you please port your UDF to CEF 3 aka Chromium Embeded Framework dll to get rid of date and buggy and breakable too often IE Trident? Please check this out to get started http://code.google.com/p/chromiumembedded/ and this for fresh hot binaries of libcef.dll http://cefbuilds.com/ Link to comment Share on other sites More sharing options...
ozmike Posted May 19, 2014 Author Share Posted May 19, 2014 Hi how would one call CEF3 from autoit ? Has anyone done that . You could try the chrome UDF '?do=embed' frameborder='0' data-embedContent>> Link to comment Share on other sites More sharing options...
Shane0000 Posted December 26, 2014 Share Posted December 26, 2014 (edited) I had been using this script successfully until it just stopped working last week. Do you know what may have happened to stop your script from working for me? When calling _OO_JSON_Init () the below line never returns. _IEDocWriteHTML($g_OO_JSON_oIE, $g_JS_HTML ) I grabbed the variable data for $g_JS_HTML (below) and saved it as a .html file. While loading this file in Internet Explorer I got a display from Internet Explorer " Internet Explorer restricted this webpage from running scripts and ActiveX controls. [Allow blocked content] " Also, allowing IECreate to return visible shows only a blank page, the 'allow blocked content' message never appears. Viewing the source shows the variable data of $g_JS_HTML. IELoadWait's (inside _IEDocWriteHTML func [iE.au3]) internal timeout (5min) seems to not be in effect also. Further digging shows that I am stuck within a loop of IELoadWait [under Case __IEIsObjType($oObject, "document") ] where as $oTemp.document.readyState = '' indefinitely $iError is set to 1 in this loop and thus never hits the timeout ElseIf statement .... Internet Explorer version 11.09600.17501 Update Versions: 11.0.15 (KB3008923) <!DOCTYPE html> <script> Object.prototype.propAdd =function(prop, val ) { eval('this.' + prop + '=' + val ) } ; Object.prototype.methAdd =function(meth, def ) { eval('this.' + meth + '= new ' + def ) } ; Object.prototype.jsFunAdd =function( funname , numParams , objectTypeName ) { var x = buildParamlist (numParams) ; objectTypeName = objectTypeName || 'Object'; return eval(objectTypeName + '.prototype.' + funname + ' = function(' + x + ') { return ' + funname + '(' + x + '); }' ) } ; function buildParamlist (numParams) { var x = ' p0' ; numParams = numParams || 1 ; for (var i=1; i< numParams; i++) { x= x + ' , ' + 'p' + i ; } ; return x; } ; Object.prototype.protoAdd =function( methName, jsFunction , objectTypeName) { objectTypeName = objectTypeName || 'Object'; eval( objectTypeName + '.prototype.' + methName + '=' + jsFunction )}; Object.prototype.objGet =function( s ) { return eval(s) } ; REM = "To get an obj $obj.objGet('JSON') "; Object.prototype.objToString =function( ) { return JSON.stringify(this) } ; REM = "Print out an object "; Object.prototype.strToObject =function( s ) { return JSON.parse(s) } ; REM = "JSON String to object "; Object.prototype.stringify =function( ) { return JSON.stringify(this) } ; REM = "Print out an object "; Object.prototype.parse =function( s ) { return JSON.parse(s) } ; REM = "JSON String to object "; Array.prototype.item =function( i ) { return this[i] } ; REM = ' so that arrays can work in AutoIT obj.item(0)' ; Object.prototype.item =function( i ) { return this[i] } ; REM = "so that dynamic key values be obtained eg. obj.item('name' ) or just obj.surname "; Object.prototype.dot =function( str, jsStrFun ) { if ( typeof str == 'string' ) { return eval( '"'+ protectDoubleQuotes (str) + '".' + jsStrFun ) } else { return eval( ''+ str + '.' + jsStrFun ) } } ; function oLiteral (literal) { this.literal = literal; } function protectDoubleQuotes (str) { return str.replace(/\\/g, '\\\\').replace(/"/g,'\\"'); } Object.prototype.toObj =function( literal ) { if ( typeof literal == 'string' ) { return eval( 'new oLiteral("' + protectDoubleQuotes (literal) + '")' ) } else {return eval( 'new oLiteral(' + literal + ')' )} } ; Object.prototype.jsMethAdd =function( funname , numParams ) { var x = buildParamlist (numParams) ; return eval('oLiteral.prototype.' + funname + ' = function(' + x + ') { return this.literal.' + funname + '(' + x + '); }' ) } ; window.onload = function() { document.body.parse = function(json) { return JSON.parse(json); }; document.body.stringify = function(obj, space) { return JSON.stringify(obj, null, space); }}</script> <body id='JSONElem'> </body> Edited December 26, 2014 by Shane0000 Link to comment Share on other sites More sharing options...
Danp2 Posted December 26, 2014 Share Posted December 26, 2014 KB3008923 caused lots of issues such as this. Have you tried installing KB3025390 to see if it resolves the issue for you? Shane0000 1 Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted December 26, 2014 Moderators Share Posted December 26, 2014 Are you using the IE-11 and the update from Dec 18th? If so, uninstall that update until they fix their issues, they broke code all across the coding communities. Shane0000 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Shane0000 Posted December 26, 2014 Share Posted December 26, 2014 Uninstalling the update KB3025390 that was released 12/18/14 did the trick. Thank you guys! Link to comment Share on other sites More sharing options...
redrider81 Posted January 4, 2015 Share Posted January 4, 2015 (edited) Great Looking UDF ozmike. Appreciate the examples. I'm new to JSON, and I'm trying to automate a web service that has a rest API. I have included my dataset below. Question 1: What's the situation on support for parsing nested items? (It's not working for me out of box). Question 2: Any advice regarding my data not having double quotes (see below)? (I see your update: eg valid JSON '{ "hello" : "world" }' invalid "{ 'hello' : 'world' }") (Do I have to do fancy stringreplace() logic to add them in before parsing?) Question 3: Can I query the json path in the nested object example below? (Can't find any reference in the documentation regarding "nested" or "query"). In xpath I could do //id[name="Group02"] which would return the id of 2. Thanks in advance to any input from anyone. Here's a sample of the output I get back from the web service: {"status": 200,"data":[{"id":1,"recipients":[{"addr":"some.guy@emailaddress.com","method":"email","comment":"","type":"admin"}],"name":"Group01"}{"id":2,"recipients":[{"addr":"some.guy@emailaddress.com","method":"email","comment":"","type":"admin"}],"name":"Group02"}{"id":3,"recipients":[{"addr":"some.guy@emailaddress.com","method":"email","comment":"","type":"admin"}],"name":"Group03"}],"errmsg":"OK"} Here's the same data formatted nicely: { "status": 200, "data": [{ "id": 1, "recipients": [{ "addr": "some.guy@emailaddress.com", "method": "email", "comment": "", "type": "admin" }], "name": "Group01" }{ "id": 2, "recipients": [{ "addr": "some.guy@emailaddress.com", "method": "email", "comment": "", "type": "admin" }], "name": "Group02" }{ "id": 3, "recipients": [{ "addr": "some.guy@emailaddress.com", "method": "email", "comment": "", "type": "admin" }], "name": "Group03" }], "errmsg": "OK" } Edited January 4, 2015 by redrider81 Link to comment Share on other sites More sharing options...
mschol Posted January 4, 2015 Share Posted January 4, 2015 Uninstalling the update KB3025390 that was released 12/18/14 did the trick. Thank you guys! thanks, also ran into problems with a script using this JSON library.. Link to comment Share on other sites More sharing options...
ozmike Posted January 5, 2015 Author Share Posted January 5, 2015 (edited) hi redrider81 Q1) You must have well formed json.. (GOOGLE online json parser Parse error on line 15: ... "Group01" }{ "id": ----------------------^ Expecting 'EOF', '}', ',', ']' Q2) you only need double quote around strings , number will be ok. so '{ "status": 200 } is ok! Q3) I'm not familiar with Xpath - but you could have a look at JSON path ( not in this UDF feel free to write a json path udf if someone else hasn't ! ) . nested should work ok for well formed JSON see Q1, Here are some examples of nested accessing you'll have to play around ! $var = '{ "status": 200 , "recipients":[{"addr":"some.guy@emailaddress.com","method":"email","comment":"","type":"admin"}] } ' $oJSON = _OO_JSON_Init() $jsObj = $oJSON.parse($var) ConsoleWrite("$jsObj.hello;-> " & $jsObj.status & @CR) ConsoleWrite("$jsObj.hello;-> " & $jsObj.recipients.item(0).addr & @CR) ConsoleWrite("$jsObj.hello;-> " & $jsObj.item("recipients").item(0).addr & @CR) Edited January 5, 2015 by ozmike Link to comment Share on other sites More sharing options...
redrider81 Posted January 5, 2015 Share Posted January 5, 2015 (edited) Thanks for the reply with specific examples ozmike. Now I understand that there are two different options for referencing a value using the dot notation. This would have been confusing without your specific example. Also, the nesting does seem to be working for at least 1 level of nesting which is encouraging. I now also understand that double quotes on the array aren't required in two cases: 1. the value is numeric 2. the value is an array of objects, in which case you use brackets to enclose the array. Learning a lot. Also, Unfortunately, writing a JSON Path UDF is beyond me because I am new to JSON, but I do believe would be helpful. In the meantime, can I easily loop through the items in a nested array so that I can search them for a specific value and return another value at the same level? For example: I want to get find all the recipients where "type"="admin", and add their "addr" (into an array) In the example you provided, would it be something like this? For $i = 0 to Ubound($jsObj.recipients) If $jsObj.recipients.type = "admin" Then _ArrayAdd($MyArray,$jsObj.recipients.addr) Next Thanks again for the UDF, and support. Edited January 5, 2015 by redrider81 Link to comment Share on other sites More sharing options...
redrider81 Posted January 5, 2015 Share Posted January 5, 2015 Also, I fixed my JSON by adding commas on lines 15 and 27, and added a second "recipient to show the level of nesting i'm actually dealing with. Here is the corrected/updated JSON. I really want to loop through and find the "id" number of the item where the name is "Group03". expandcollapse popup{ "status": 200, "data": [{ "id": 1, "recipients": [{ "addr": "some.guy1@emailaddress.com", "method": "email", "comment": "", "type": "admin" }], "name": "Group01" }, { "id": 2, "recipients": [{ "addr": "some.guy2@emailaddress.com", "method": "email", "comment": "", "type": "admin" }], "name": "Group02" }, { "id": 3, "recipients": [{ "addr": "some.guy3data@emailaddress.com", "method": "email", "comment": "", "type": "admin" }, { "addr": "some.guy3voice@emailaddress.com", "method": "voice", "comment": "", "type": "admin" }], "name": "Group03" }], "errmsg": "OK" } Link to comment Share on other sites More sharing options...
ozmike Posted January 6, 2015 Author Share Posted January 6, 2015 Hi Here is what you want, notice you can't use UBound($obj.data) - Ubound is an auto it function. I have a length property which you can use in autoit. $oJSON = _OO_JSON_Init() $var = '{ "data": [{ "id": 1, "recipients": [{ "type": "admin" }], "name": "Group01" } , { "id": 2, "recipients": [{ "type": "admin" }], "name": "Group03" }] }' $jsObj = $oJSON.parse($var) For $i = 0 to $jsObj.data.length - 1 if $jsObj.data.item($i).name = "Group03" Then ConsoleWrite("id found ->" & $jsObj.data.item($i).id & @CR) endif next Exit Alternatively try this >json UDF, someone has written _JSONGet($json, "test.x.2") for this udf. this udf is not as object oriented as mine. The _JSONGet or similar could be ported to my UDF ;USING JSON.UDF! create an json object to test Local $json = _JSONDecode('{"test":{"x":[11,22,{"y":55}]}}') ;query this object Local $result = _JSONGet($json, "test.x.2") Link to comment Share on other sites More sharing options...
redrider81 Posted January 8, 2015 Share Posted January 8, 2015 (edited) Awesome! I will try that loop at my next opportunity. Indeed it would be great if someone ported those Get and Set functions to your OO_JSON.au3 UDF (which seems to be the most favorable one thus far). Until then, if I wanted to return an array of all group names which contain a "type":"admin", is a nested for loop that manually stores the results into an array the best way to do that? Edited January 8, 2015 by redrider81 Link to comment Share on other sites More sharing options...
ozmike Posted January 8, 2015 Author Share Posted January 8, 2015 (edited) Hi Just build up a json string for the array ["Group01","Group03"] and then create array..from that.(or you could load it into an Auto it array) I'm having a playing with json path ...be some time off.. $oJSON = _OO_JSON_Init() $var = '{ "data": [{ "id": 1, "recipients": [{ "type": "admin" }], "name": "Group01" } , { "id": 2, "recipients": [{ "type": "admin" }], "name": "Group03" }] }' $jsObj = $oJSON.parse($var) $array_text = "[" For $i = 0 to $jsObj.data.length - 1 if $jsObj.data.item($i).recipients.item(0).type = "admin" Then $array_text = $array_text & """" & $jsObj.data.item($i).name & """," endif next $array_text = $array_text & """""]" ConsoleWrite("array ->" & $array_text & @CR) $jsObj = $oJSON.parse($array_text) ConsoleWrite("$jsObj.item(1) ->" & $jsObj.item(1) & @CR) _OO_JSON_Quit ( ) Exit Edited January 8, 2015 by ozmike Link to comment Share on other sites More sharing options...
redrider81 Posted January 11, 2015 Share Posted January 11, 2015 (edited) 1. I will be looking forward to that addition when you get some time. 2. I will use an AutoIt Array. CSV.au3 includes two very useful functions: "_WriteCSV()" and "_ParseCSV()". This enables very easy importing and exporting for my programs for any data that I put into a 2-Dimensional Array (which is what i'll be doing with many of the JSON objects I am working with). 3. I will be spending my time figuring out the best ways to loop through all the JSON Objects at a particular level, and put their properties into an AutoIt Array so that I can then use _WriteCSV() to export. Then my team can update the CSV, and re-import it using the reverse process. Thanks again for all your tremendous work with this UDF. It really among the best I've ever seen. EDIT: Step 3 appears to be much more difficult than I anticipated because there is no native way to enumerate through "all" properties of an object when you don't know their names or how many there are. Apparently it's a feature of some languages and not others. This is my conclusion based on what I've read... can anyone confirm that this correct? Edited January 11, 2015 by redrider81 Link to comment Share on other sites More sharing options...
redrider81 Posted January 12, 2015 Share Posted January 12, 2015 I did this string and array manipulation in the meantime. To anyone trying to reference this, sorry for the lack of comments... Also sorry I can't provide the JSON string. In theory should work for any JSON. In my particular JSON data, a host has normal JSON properties, and then additional properties under a "properties" object. It's not nice. If not for this, you could simply remove the second line of code. $sHostObject = $oGetHostsObject.data.hosts.item(0).stringify() $sHostProperties = StringReplace($sHostObject,'properties":{"','') ; Remove properties":{" so that all properties appear at same level $sHostProperties = StringReplace($sHostProperties,'{"','') ; Remove special character $sHostProperties = StringReplace($sHostProperties,'}','') ; Remove special character _ArrayAdd($aHostProperties,$sHostProperties,0,':',',"') ; _ArrayAdd supports a delimiter for both dimensions... worked out well. For $i = 0 to Ubound($aHostProperties)-1 For $j = 0 to Ubound($aHostProperties,2)-1 $aHostProperties[$i][$j] = StringReplace($aHostProperties[$i][$j],'"','') ; Clean the remaining double quotes Next Next _ArrayDisplay($aHostProperties) Link to comment Share on other sites More sharing options...
ozmike Posted January 12, 2015 Author Share Posted January 12, 2015 (edited) This is how to list properties, tell its type or tell is its an array. Note , you can extend my UDF without changing code in the UDF..! see protoAdd $oJSON = _OO_JSON_Init() $var = '{ "data": [{ "id": 1, "recipients": [{ "type": "admin" }], "name": "Group01" } , { "id": 2, "recipients": [{ "type": "admin" }], "name": "Group03" }] }' $jsObj = $oJSON.parse($var) $jsObj.protoAdd( "getKeys2", " function( s ) { if (typeof s == 'object') { return Object.keys(s);} }; ") $jsObj.protoAdd( "getType2", " function( s ) { return typeof(s); }; ") $jsObj.protoAdd( "isArray2", " function( s ) { return Array.isArray(s); }; ") $keys = $jsObj.getKeys2( $jsObj.item("data").item(0) ) ConsoleWrite("keys of $jsObj.item(""data"").item(0) ->" & $keys.stringify() & @CR) ; ->["id","recipients","name"] $value = $jsObj.isArray2( $jsObj.item("data").item(0) ) ConsoleWrite("isArray $jsObj.item(""data"").item(0) ->" & $value & @CR) ; ->false $type = $jsObj.getType2( $jsObj.item("data").item(0)) ConsoleWrite("type $jsObj.item(""data"").item(0) ->" & $type & @CR & @CR) ; ->object $keys = $jsObj.getKeys2( $jsObj.item("data") ) ConsoleWrite("keys of $jsObj.item(""data"") ->" & $keys.stringify() & @CR) ;->["0","1"]? $value = $jsObj.isArray2( $jsObj.item("data") ) ConsoleWrite("isArray $jsObj.item(""data"") ->" & $value & @CR) ; ->true $type = $jsObj.getType2( $jsObj.item("data")) ConsoleWrite("type $jsObj.item(""data"") ->" & $type & @CR & @CR) ; ->object $keys = $jsObj.getKeys2( $jsObj.item("data").item(0).id ) ConsoleWrite("keys of $jsObj.item(""data"").item(0).id ->" & $keys & @CR) ; blank no keys! not an object $type = $jsObj.getType2( $jsObj.item("data").item(0).id ) ConsoleWrite("type $jsObj.item(""data"").item(0).id ->" & $type & @CR) ; number $type = $jsObj.getType2( $jsObj.item("data").item(0).name ) ConsoleWrite("type $jsObj.item(""data"").item(0).name ->" & $type & @CR) ; string _OO_JSON_Quit ( ) BTW if you need to get into a autoit array maybe look at the other JSON udf i mentioned ...as it dumps • JSON arrays are decoded “as-is” to one-dimensional AutoIt arrays Edited January 13, 2015 by ozmike Link to comment Share on other sites More sharing options...
redrider81 Posted January 14, 2015 Share Posted January 14, 2015 (edited) Hi ozmike, Another challenge if you have the time. Just when I thought I was getting good with this UDF and JSON, I found something I don't know how to do: take an AutoIt Array, and build a JSON object array out of it. Also, to add to the difficulty, at least one JSON property value will be an object array of it's own. I know the other UDF's provide some JSON to Array migration functions but once again, I only want to use your UDF if possible. Your methods are excellent, but to be honest I can still barely wrap my head around them. Also, extending with ProtoAdd or combining with other UDF is way beyond me at this time. My first problem is basic, is that I can't see how to add a "Property" an array of objects when starting with an empty object. The examples show the object items parsed upon creation. I do this to define the structure: $jsObj = $oJSON.parse( '{}' ) $jsObj.propAdd("data") $jsObj.data.propAdd("name") $jsObj.data.propAdd("id") $jsObj.data.propAdd("recipients") $jsObj.data.recipients.propAdd("addr") $jsObj.data.recipients.propAdd("method") $jsObj.data.recipients.propAdd("comment") $jsObj.data.recipients.propAdd("type") .... but I don't know what to do next. I tried several things. Here's a model of the source data. I import via CSV using _ParseCSV() #include <Array.au3> Global $array[1][6] = [['recipientGroupName','recipientGroupId','addr','method','comment','type']] $string='"LOW"|100|Group1|||"group"' & @CRLF & '"LOW"|100|Group2|||"group"' $string&= @CRLF & '"MED"|200|Group4|||"group"' & @CRLF & '"MED"|200|Group5|||"group"' $string&= @CRLF & '"HIGH"|300|Group7|||"group"' & @CRLF & '"HIGH"|300|Group8|||"group"' _ArrayAdd($array,$string) _ArrayDisplay($array) Here's the JSON object I want to make from it: expandcollapse popup{ "data" : [{ "id" : 100, "recipients" : [{ "addr" : "Group1", "method" : "", "comment" : "", "type" : "group" }, { "addr" : "Group2", "method" : "", "comment" : "", "type" : "group" } ], "name" : "Groups_LOW" }, { "id" : 200, "recipients" : [{ "addr" : "Group4", "method" : "", "comment" : "", "type" : "group" }, { "addr" : "Group5", "method" : "", "comment" : "", "type" : "group" } ], "name" : "Groups_MED" }, { "id" : 300, "recipients" : [{ "addr" : "Group7", "method" : "", "comment" : "", "type" : "group" }, { "addr" : "Group8", "method" : "", "comment" : "", "type" : "group" } ], "name" : "Groups_HIGH" } ] } Edited January 14, 2015 by redrider81 Link to comment Share on other sites More sharing options...
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