Jump to content

OO_JSON.UDF, JSON/path, OO, using javascript in Auto IT


ozmike
 Share

Recommended Posts

Ok your on the right track..you just need to work out how to do an JSON array

try to build the objects from the inside out ie. build small object and test them and join together.

i have no method to add an item to an array (yet) so you must build up a json string that represent the array and parse it back

I haven't tested this fully but hopefully this will help you..This hopefully creates a recipents array of two items 

$jsObj.propAdd("addr")
$jsObj.propAdd("method", "'mymethvalue'")
$jsObj.propAdd("comment")
$jsObj.propAdd("type")
$jsObj.addr = "mytext";
ConsoleWrite( "$jsObj.addr " &  $jsObj.addr & @CR )
ConsoleWrite( "$jsObj.method " &  $jsObj.method & @CR )

$recipients = $oJSON.parse('[ ' & $jsObj.stringify() & ' ,'  & $jsObj.stringify() & ' ]'; array
ConsoleWrite( "$recipients.item(0).stringify() " &  $recipients.item(0).stringify() & @CR )
$jsObj2 = $oJSON.parse( '{}' )
$jsObj2.propAdd("recipients")
$jsObj2.recipients = $recipients
Edited by ozmike
Link to comment
Share on other sites

Thanks Again!

To be honest, I was afraid that might be the way.  Your suggestion is to use string manipulation to loop through the AutoIt array and build the JSON array, and I can do that. My end goal is to submit the data in string format to an API, which takes a property=value syntax.  I had built a nice JSON-to-API String converter, so I was hoping to go Array-JSON-API-String using nice UDF methods.  Here, I might as well just work on going straight from Array-To-APIString 

I wish I had the time to learn enough to work on consolidating the features of the other JSON UDFs into yours. There are a bunch of new services that we've recently started using (Microsoft Azure Datacenter Migration Tool for example) which all have API's that are JSON based.  I am sure I will end up taking your suggestions and making something very dynamic out of them, and eventually I promise I will post them back here.  Unfortunately, they probably won't be UDF calibur / material. 

 

Regards,
Jerry 

Link to comment
Share on other sites

Hi No worries

Anyway, I've added a arrayAdd method using the protoAdd (see below example of building an array). You could use this build your JSON object then stringfy() it out to your API.

This UDF does need some methods to goto autoit arrays but its good for reading JSON and doing OO.

In the future I will add json path and make the UDF independent of IE as the latest updates of IE (dec-2014) broke the UDF , but the non_IE version still works..

But anyway its good to see how someone might use this UDF! thanks

cheers

$oJSON = _OO_JSON_Init()
$jsObj = $oJSON.parse('{}')
$jsObj.protoAdd( "isArray2", " function( s ) { return Array.isArray(s); }; ")
$jsObj.protoAdd( "ArrayAdd", " function( a,i, o ) { a[i] = o; return a; }; ")
$jsObj = $oJSON.parse('[]')
ConsoleWrite("isArray $jsObj.isArray2( $jsObj ) ->" & $jsObj.isArray2( $jsObj ) & @CR) ;  ->true
ConsoleWrite("array $jsObj.stringify()  ->" & $jsObj.stringify() & @CR) ; ->[]
$jsObj = $oJSON.ArrayAdd($jsObj, 0, "test")
ConsoleWrite("array $jsObj.stringify()  ->" & $jsObj.stringify() & @CR) ; ->["test"]
$jsObj2 = $oJSON.parse('{ "hello" : "world" } ')
$jsObj = $oJSON.ArrayAdd($jsObj, 1, $jsObj2)
ConsoleWrite("array $jsObj.stringify()  ->" & $jsObj.stringify() & @CR) ; ->["test",{"hello":"world"}]
_OO_JSON_Quit (  )
Edited by ozmike
Link to comment
Share on other sites

But anyway its good to see how someone might use this UDF! thanks

I plan to use this UDF in my TeamViewer API UDF

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

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

 

MIke... just tested this code and it works!!  However, when we go to USE the key/property names... we hit another stumbling block...this one is more fundamental I think. 

The dot-notation does not appear to be able to take variables in line as part of the call... see below. 

In the above example, we loop through the keys and print the key names.  The first key is "id" which can be printed via: 

Consolewrite($keys.item(0))

If we knew the key name ahead of time, we could then print the value for that key as follows:

Consolewrite($jsObj.item("data").item(0).id)

However, the impossible part seems to be to represent the "id" using a variable as follows: 

$keyname = "id" 
Consolewrite($jsObj.item("data").item(0).$keyname)

Let alone what we are actually trying to do, which is nest it like this: 

Consolewrite($jsObj.item("data").item(0).($keys.item(0)))

Please just confirm that this is a fundamentally impossible thing to do and I'll move on. 

Link to comment
Share on other sites

Yes all is possible! you can go item($var) your last attempt was very close..!

$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);}   }; ")
$keys = $jsObj.getKeys2( $jsObj.item("data").item(0) )
ConsoleWrite("keys of $jsObj.item(""data"").item(0)  ->" & $keys.stringify() & @CR) ; ->["id","recipients","name"]
$fieldname =  $keys.item(0)
ConsoleWrite("keys of $jsObj.item(""data"").item(0)  ->" & $keys.item(0) & @CR) ; ->["id","recipients","name"]
ConsoleWrite("keys of $jsObj.item(""data"").item(0)  ->" & $jsObj.item("data").item(0).item($fieldname) & @CR) ; ->["id","recipients","name"]

 my framework takes care of it ..don't ask me how it works!  The power of javascript!

" Object.prototype.item           =function( i ) { return this[i] }                ;  REM = ""so that dynamic key values be obtained eg. obj.item('name' ) or just obj.surname ""; "
Edited by ozmike
Link to comment
Share on other sites

Yeah this udf is a bit tricky ..I have a version with json path working . Also have to update to work around the IE 11 updates which happened in dec 2014 ..which broke the existing UDF,

Edited by ozmike
Link to comment
Share on other sites

Is the dependency situation with the three extra files explained anywhere? 

Is there a reason you did not just incorporate/embed these files into the UDF? 

I can see some benefit to keeping external "Packages" external (easy to replace when an update comes out, etc). However from my perspective, that's outweighed by the disadvantage of having to remember to lug them around with the UDF. 

Thanks again!

Link to comment
Share on other sites

ozmike-

Just wanted to say thank you so much for doing this.  I'm having a little problem getting up and running though.  I've downloaded the v7 stuffit.gif  JSON_OO v7.zip   14.38KB and extracted it.  Once extracted I tried running the "OO_JSON_example.au3" in the folder.  I get an error in the file of the "OO_JSON.au3" ,error is:

C:Program Files (x86)AutoIt3IncludeOO_JSON.au3" (173) : ==> Variable must be of type "Object".:

$js.language = "Jscript"

$js^ ERROR"

I'm assuming the error is originates from the line above of:

$g_OO_JSON_non_IE = ObjCreate("ScriptControl")

Am I missing a download or additional import to not create the object?

thank you for your time

Link to comment
Share on other sites

Try This,,see if you get a @error = 1

$g_OO_JSON_non_IE = ObjCreate("ScriptControl")
ConsoleWrite(  "@error " & @error & @CR ) ;--> 0 ok
ConsoleWrite(  "isObj($g_OO_JSON_non_IE):" & isObj($g_OO_JSON_non_IE)& @CR  ) ;--> 1 object

Try downloading the windows script object..

http://www.microsoft.com/en-us/download/details.aspx?id=1949

Also see auto it help file Obj/COM Reference in there , there is a section on the OLE/COM Object Viewer - which you may be able to use to see if you have it installed.

http://download.microsoft.com/download/2/f/1/2f15a59b-6cd7-467b-8ff2-f162c3932235/ovi386.exe

Link to comment
Share on other sites

HI redrider81

 

The external files are a pain, but its for easy upgrades ,  eg yes could use json3.js instead of json2.txt 

To build the  files into the UDF I would have to convert the files from text to a string variable ...a nightmare ..considering double quotes..etc..

Leaving them external the json code is not modified = JSON compliant  & no bugs! 

In the future I hope to let you import whatever json , jsonpath file version you require as part of the init function.

Another option is to pull files from  the internet on the fly this way you would not need external files but a internet connection?

Link to comment
Share on other sites

I've installed the windows script object and windows viewer as you've said.

My consolewrite shows this:

@error -2147221164
isObj($g_OO_JSON_non_IE):0
"C:\Program Files (x86)\AutoIt3\Include\OO_JSON.au3" (181) : ==> Variable must be of type "Object".:
$js.language = "Jscript"
$js^ ERROR
 
I use windows 8.1, would that have anything to do with this error?
Link to comment
Share on other sites

HI redrider81

The external files are a pain, but its for easy upgrades ,  eg yes could use json3.js instead of json2.txt 

To build the  files into the UDF I would have to convert the files from text to a string variable ...a nightmare ..considering double quotes..etc..

Leaving them external the json code is not modified = JSON compliant  & no bugs! 

In the future I hope to let you import whatever json , jsonpath file version you require as part of the init function.

Another option is to pull files from  the internet on the fly this way you would not need external files but a internet connection?

 

Interesting idea doing something like GRAPE where it pulls dependencies from the internet at runtime / compiletime.  The hosting/URL location would have to be reliable and robust long-term, but thats not impossible.  To be honest, it depends on where AutoIt is going for the future.  Does it work in Windows 10, is the community going to continue, etc.  

It does appear that there is no reasonable alternative to the external files. It's a bummer, but livable. I guess in every other IDE/Language you rely on external libraries which rely on other external libraries... but at least there you can put them all in a /lib directory. Wait... can we do something similar, like save the json2.txt as an  .au3  file and put it in the Includes directory and treat it like any other include?  At least then it wouldn't need to be copied to every project directory and it wouldn't stick out like such a sore thumb. 

Regards,

Jerry

Link to comment
Share on other sites

Ok this is what you want ...i'll leave it to you to play with it...

 

'?do=embed' frameborder='0' data-embedContent>>

; add to OO_JSON
#AutoIt3Wrapper_Res_File_Add=json2.txt, rt_rcdata, JSON_TXT_2

#include "resources.au3"

; $json_text = _OO_JSON_Read_File("json2.txt") ; replace this line in oo_json.udf - do for each file,
$json_text = _ResourceGetAsString("JSON_TXT_2")

 

 

Edited by ozmike
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...