Jump to content

A Non-Strict JSON UDF (JSMN)


Ward
 Share

Recommended Posts

Implementation of the JSMN using Map available in Autoit Beta (3.3.15):

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****


#include "jsonMap.au3"

$json = '{"test":"yay"}'
$test = Json_Decode($json)
ConsoleWrite($test['test'] & @CRLF)

$test['test'] = 'horray!!!'
ConsoleWrite($test['test'] & @CRLF)

ConsoleWrite(Json_Encode($test) & @CRLF)

 

 

jsonMap.au3

Edited by dexto
Fixed a bug in the Json_Encode_Pretty()
Link to comment
Share on other sites

31 minutes ago, dexto said:

Implementation of the JSMN using Map

so, what is the use of the addition of

Local $default[]
If $json = "" Then Return SetError(0, 1, $default)

Edit: ok, got it.

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

  • 4 weeks later...

Edit of my answer on the importance of simple and double quote.

Quote

$akeys = Json_ObjGetKeys($JsoEqpt)

    Json_Get($JsoEqpt, '["' & $akeys[0] & '"]["tagInge"]')        => OK  Key between Double quotes:   '   [   "   '   & $akeys
    Json_Get($JsoEqpt, '["' & $akeys[0] & "']['tagInge']")        => Not OK, key between simple quotes    "   [   '   "   & $akeys

    I must indicate that my keys are Numbers only overwise i think it's ok with string key!

 

 

 

 

Link to comment
Share on other sites

  • 1 month later...

hi guys !!! how are you ? fine ? nice !!!

does anyone has encountered problems, using several Json ?

I encounter a problem, i just can't success in creating a simple example to show you but i can show you a part of it :'(

Context: in my code i use 2 json, the final one, and the other is for temporary use, (in a loop and clear).

The deal is to create an array of object and add it to my json. It's ok but an array is modified when i modifiy the other... i'm going crazy...:mad:

 

I m gonna show you state of my 2 json, a jsonclear of the first one, and the second is affected too..(it change !)

 

Sorry again not giving usable example... but maybe this will gave you ideas...

Problem just with adding something to a json, the other is affected.

ConsoleWrite("Just any text to show you this is the good part of the code..." & @crlf)
                            ConsoleWrite("$JsonPopupEqpt:" & json_encode($JsonPopupEqpt) & @CRLF)
                            ConsoleWrite("$Jsontemporaire:" & json_encode($Jsontemporaire) & @CRLF)
                            ConsoleWrite("$aema:" & $aema & @CRLF )
                            ConsoleWrite("$letexte:" & $letexte & @CRLF )
                            Json_Put($Jsontemporaire, '["AEMA"]', $aema)
                            Json_Put($Jsontemporaire, '["NumeroSerie"]', $letexte)
                            ConsoleWrite("has Json_Popup_Eqpt change ?:" &json_encode($JsonPopupEqpt) & @CRLF  )
                            ConsoleWrite("Just any text  blablabla" & @crlf)

Console output:

Spoiler

Just any text to show you this is the good part of the code...
$JsonPopupEqpt:{"ListeAEMA_NS_Depose":[],"ListeAEMA":"","ListeNS":"","ListeAEMA_NS_Reprise":[{"AEMA":"AEMARAD00040","NumeroSerie":"1625004894"}],"Mouvement":"Remplacement"}
$Jsontemporaire:{"AEMA":"AEMARAD00040","NumeroSerie":"1625004894"}
$aema:AEMANBE00200
$letexte:F207420006029
has Json_Popup_Eqpt change ?:{"ListeAEMA_NS_Depose":[],"ListeAEMA":"","ListeNS":"","ListeAEMA_NS_Reprise":[{"AEMA":"AEMANBE00200","NumeroSerie":"F207420006029"}],"Mouvement":"Remplacement"}
Just any text  blablabla

 

Please note that the JsonPopupEqpt is not the same, i just don't touch it.

 

Problem just with an Objclear the other json is affected.

ConsoleWrite("Just any text to show you this is the good part of the code..." & @crlf)
                            ConsoleWrite("$JsonPopupEqpt:" & json_encode($JsonPopupEqpt) & @CRLF)
                            ConsoleWrite("$Jsontemporaire:" & json_encode($Jsontemporaire) & @CRLF)
                            ConsoleWrite("$aema:" & $aema & @CRLF )
                            ConsoleWrite("$letexte:" & $letexte & @CRLF )
                            Json_ObjClear($Jsontemporaire)
                            ConsoleWrite("has Json_Popup_Eqpt change ?:" &json_encode($JsonPopupEqpt) & @CRLF  )
                            ConsoleWrite("$Jsontemporaire:" & json_encode($Jsontemporaire) & @CRLF)
                            ConsoleWrite("Just any text  blablabla" & @crlf)

 

Console output:

Spoiler

Just any text to show you this is the good part of the code...
$JsonPopupEqpt:{"ListeAEMA_NS_Depose":[],"ListeAEMA":"","ListeNS":"","ListeAEMA_NS_Reprise":[{"AEMA":"AEMARAD00040","NumeroSerie":"1625004894"}],"Mouvement":"Remplacement"}
$Jsontemporaire:{"AEMA":"AEMARAD00040","NumeroSerie":"1625004894"}
$aema:AEMANBE00200
$letexte:F207420006029
has Json_Popup_Eqpt change ?:{"ListeAEMA_NS_Depose":[],"ListeAEMA":"","ListeNS":"","ListeAEMA_NS_Reprise":[{}],"Mouvement":"Remplacement"}
$Jsontemporaire:{}
Just any text  blablabla

Note that my json JsonPopupEqpt has it field ListeAEMA_NS_Reprise reset.... d'ont know why

They are all created with

local $JsonPopupEqpt
    If Json_IsObject($JsonPopupEqpt) Then
        Json_ObjClear($JsonPopupEqpt)
    Else
        $JsonPopupEqpt = Json_ObjCreate()
    EndIf

I've tried, renaming the jsons, (in case there are the same name is the udf), i removed the initial '_' in the name...

I'm running out of ideas...

 

I give you poor information, and no example to test, i'm sorry for that... i can't reproduce in a standalone program.

So i just ask for ideas... thanks for your comprehension

Nicolas.

Edited by satanico64
correct errors
Link to comment
Share on other sites

hi, and thanks for your answer, everything help :)

 

For sure i modify an object, it's what i want.

The 2 objects i show in my example are different ( but with same fields/type ) but i modify the first ,one the second is modified too...

I thing there is something wrong with the format. I got the problem if i modify the object, and even if i clear the object.

 

Format of my json is: { Array1 [ object, object, object...] , Array2 [ object, object, object...] }

I thing something goes wrong using array of objects, or maybe the fact i had initialised an empty array in my json

 

Indeed, i just bypass the problem using notation and only one Json::)

i just erased all, and totally rewrite...

something like:

local $JsonPopupEqpt
    If Json_IsObject($JsonPopupEqpt) Then
        Json_ObjClear($JsonPopupEqpt)
    Else
        $JsonPopupEqpt = Json_ObjCreate()
    EndIf

    Json_Put($JsonPopupEqpt, ".ListeAEMA_NS_Reprise[0].AEMA", $aema)
    Json_Put($JsonPopupEqpt, ".ListeAEMA_NS_Reprise[0].NumeroSerie", $ns)    
    Json_Put($JsonPopupEqpt, ".ListeNS", $ListeNS)
    
    ; my loop has disappear and is replaced now by: 
     $i = UBound(Json_Get($JsonPopupEqpt,".ListeAEMA_NS_Depose") )
        Json_Put($JsonPopupEqpt, ".ListeAEMA_NS_Depose[" & $i & "].AEMA", $aema)
        Json_Put($JsonPopupEqpt, ".ListeAEMA_NS_Depose[" & $i & "].NumeroSerie", $letexte)

code shorter, cleaner and it works.

Do you know any tip to get array size in the json ?

i use  $i = UBound(Json_Get($JsonPopupEqpt,".ListeAEMA_NS_Depose") )  , it works but maybe there's a different way...

 

Thanks

Nicolas

Link to comment
Share on other sites

  • 2 weeks later...

Hi Ward

The keys of type "integer" or of type "string" are allowed in Map variable (Autoit) (as well as in scripting dictionary), and are not the same.
The Json encoding results in a change of type of keys, type "integer".
Example:

#include <Array.au3>
#include "JsonMap.au3"

ConsoleWrite("======================== MAP ===========================" & @CRLF)
;-- Tableau 2D à include dans la Map --
    Global $aTest1[2] = ['ROUGE', 'VIOLET']

    Global $Map[], $MapOut
    $Map["Cle1"] = "DataCle1"
    $Map["Cle2"] = "DataCle2"
    $Map["2"] = "DataCleString"
    $Map[2] = "DataCleNum"
    $Map["Cle3"] = $aTest1

    Global $code = Json_Encode($Map)
    ConsoleWrite('Map     Code: ' & $code & @CRLF)

    $MapOut = Json_Decode($code)

    ;-- Affichages -------------------------------
    Global $aKeys = MapKeys ($MapOut)
;~  _ArrayDisplay ($aKeys)
    ConsoleWrite("Type Cle1 = " & VarGetType($aKeys[0]) & @CRLF)
    ConsoleWrite("Type Cle2 = " & VarGetType($aKeys[1]) & @CRLF)
    ConsoleWrite('Type "2" = ' & VarGetType($aKeys["2"]) & @CRLF)
    ConsoleWrite("Type 2 = " & VarGetType($aKeys[2]) & @CRLF)

    ConsoleWrite("$MapOut[Cle1]= " & $MapOut["Cle1"] & @CRLF)
    ConsoleWrite("$MapOut[Cle2]= " & $MapOut["Cle2"] & @CRLF)
    ConsoleWrite('$MapOut["2"]= ' & $MapOut["2"] & @CRLF)
    ConsoleWrite("$MapOut[2]= " & $MapOut[2] & @CRLF)
;~  _ArrayDisplay($MapOut["Cle3"])

    ;-- Nouveau codage du résultat ----------
    Global $codeOut = Json_Encode($MapOut)
    ConsoleWrite('MapOut     Code: ' & $codeOut & @CRLF)

    ;-- comparaison des codes ---------------
    If $codeOut = $code Then
        ConsoleWrite("$codeOut = $code" & @CRLF)
    Else
        ConsoleWrite("$codeOut <> $code" & @CRLF)
    EndIf

result:

Spoiler

======================== MAP ===========================
Map     Code: {"Cle1":"DataCle1","Cle2":"DataCle2","2":"DataCleString","2":"DataCleNum","Cle3":["ROUGE","VIOLET"]}
Type Cle1 = String
Type Cle2 = String
Type "2" = String
Type 2 = String
$MapOut[Cle1]= DataCle1
$MapOut[Cle2]= DataCle2
$MapOut["2"]= DataCleNum
$MapOut[2]=
MapOut     Code: {"Cle1":"DataCle1","Cle2":"DataCle2","2":"DataCleNum","Cle3":["ROUGE","VIOLET"]}
$codeOut <> $code

Kind regards.

Edited by MimiOne

I'm not always in my opinion...

Link to comment
Share on other sites

  • 1 month later...

Hi. I can not get value of 'dst' attr from JSON:

{"trans_result":{"from":"en","to":"zh","domain":"all","type":2,"status":0,"data":[{"dst":"\u6d4b\u8bd5","src":"test","relation":[],"result":[[0,"\u6d4b\u8bd5",["0|4"],[],["0|4"],["0|6"]]]}],"phonetic":[{"src_str":"\u6d4b","trg_str":"c\u00e8"},{"src_str":"\u8bd5","trg_str":"sh\u00ec"}]}}

This is table:

$aJSON['trans_result']['data']

But

$aJSON['trans_result']['data'][0]

gives an error message: Array variable has incorrect number of subscripts or subscript dimension range exceeded.

 

Link to comment
Share on other sites

  • Developers

What is your code to retrieve the field so we can have a look?
Also which include file are you using?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

My func:

Func _URIEncode($sData)
    Local $aData = StringSplit(BinaryToString(StringToBinary($sData, 4), 1), "")
    Local $nChar
    $sData = ""
    For $i = 1 To $aData[0]
        $nChar = Asc($aData[$i])
        Switch $nChar
            Case 45, 46, 48 To 57, 65 To 90, 95, 97 To 122, 126
                $sData &= $aData[$i]
            Case 32
                $sData &= "+"
            Case Else
                $sData &= "%" & Hex($nChar, 2)
        EndSwitch
    Next
    Return $sData
EndFunc   ;==>_URIEncode
Func _GetTranslateBaidu($sText)
    Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
    $oHTTP.Open("Post", "http://translate.baidu.com/v2transapi", False)
    $oHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
    $oHTTP.SetRequestHeader("Host", 'translate.baidu.com')
    $oHTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36")
    $oHTTP.SetRequestHeader("Connection", "keep-alive")

    ConsoleWrite('from=en&to=zh&query=' & _URIEncode($sText) & '&transtype=translang&simple_means_flag=3' & @CRLF)

    $oHTTP.Send('from=en&to=zh&query=' & _URIEncode($sText) & '&transtype=translang&simple_means_flag=3')
    If ($oHTTP.Status == 200) Then
        $sJSON = $oHTTP.ResponseText
        $aJSON = Json_Decode($sJSON, 10000)
        ConsoleWrite($aJSON['trans_result']['data'][0]['dst'] & @CRLF)
    EndIf
EndFunc   ;==>_GetTranslateBaidu

Include: jsonMap.au3

Edited by AMSPeople
Link to comment
Share on other sites

You can do this:

Local $oJson = Json_Decode($sJson)
Local $dst=Json_Get($oJson,'["trans_result"]["data"][0]["dst"]')

Saludos

Link to comment
Share on other sites

 

 error: Json_Get(): undefined function.

I use jsonMap:

Udf from the first post can not be downloaded.

I found in another location JSON.au3 library from ward.

There was another question. Can I somehow know the number of elements inside the element ["trans_result"] ["data"]?
Since variants are possible ["trans_result"] ["data"] [0] ["dst"], ["trans_result"] ["data"] [1] ["dst"], ["trans_result"] ["data "] [2] [" dst "] and so on.

 

$oJSON = Json_Decode($sJSON)
        Local $aLines = Json_Get($oJSON, '["trans_result"]["data"]')
        For $i = 0 To UBound($aLines) - 1
            $sDst = Json_Get($oJSON, '["trans_result"]["data"][' & $i & ']["dst"]')

            MsgBox(0, '', $sDst)
            ConsoleWrite($sDst & @CRLF)
        Next

 

Edited by AMSPeople
Link to comment
Share on other sites

13 hours ago, AMSPeople said:

Hi. I can not get value of 'dst' attr from JSON:

{"trans_result":{"from":"en","to":"zh","domain":"all","type":2,"status":0,"data":[{"dst":"\u6d4b\u8bd5","src":"test","relation":[],"result":[[0,"\u6d4b\u8bd5",["0|4"],[],["0|4"],["0|6"]]]}],"phonetic":[{"src_str":"\u6d4b","trg_str":"c\u00e8"},{"src_str":"\u8bd5","trg_str":"sh\u00ec"}]}}

This is table:

$aJSON['trans_result']['data']

But

$aJSON['trans_result']['data'][0]

gives an error message: Array variable has incorrect number of subscripts or subscript dimension range exceeded.

 

 

 

So it is also easy with jsonMap :)

Global $sString = '{"trans_result":{"from":"en","to":"zh","domain":"all","type":2,"status":0,"data":[{"dst":"\u6d4b\u8bd5","src":"test","relation":[],"result":[[0,"\u6d4b\u8bd5",["0|4"],[],["0|4"],["0|6"]]]}],"phonetic":[{"src_str":"\u6d4b","trg_str":"c\u00e8"},{"src_str":"\u8bd5","trg_str":"sh\u00ec"}]}}'
Global $mMap = Json_Decode($sString)
Global $aArray = $mMap.trans_result.data
Global $mData = $aArray[0]

ConsoleWrite($mData.dst & @CRLF)

 

Edited by Taz77
Link to comment
Share on other sites

  • 2 months later...
  • 1 month later...

How do you get a count of elements within an array? Json_ObjGetCount doesn't seem to be it.

#Include "JSon.au3"

Local $Json = '{"name":"John","cars":[ "Ford", "BMW", "Fiat", "Chevy" ]}'

;Correctly returns a count of 2 elements (name and cars)
Local $Obj = JSon_Decode($Json)
ConsoleWrite("count root: " & Json_ObjGetCount($Obj) & @CRLF) 

;Returns error Variable must be of type "Object"
Local $Cars = Json_ObjGet($Obj, '["cars"][0]')
ConsoleWrite("count cars: " & Json_ObjGetCount($aCars) & @CRLF)

Or is the only way to first loop through the array and make my own counter, then go back through and reference what I want to do?

Link to comment
Share on other sites

On 10/12/2017 at 11:15 PM, TheDcoder said:

@Decibel Use Ubound($aCars) to get count of an array.

Thanks. I didn't realize that the JSON Arrays were "just arrays." Solution provided below for others.

#Include "JSon.au3"
    
    Local $Json = '{"name":"John","cars":[ "Ford", "BMW", "Fiat", "Chevy" ]}'

    ;Correctly returns a count of 2 elements (name and cars)
    Local $Obj = JSon_Decode($Json)
    ConsoleWrite("count root: " & Json_ObjGetCount($Obj) & @CRLF)

    ;Returns error Variable must be of type "Object"
    ;Local $Cars = Json_ObjGet($Obj, '["cars"][0]')
    ;ConsoleWrite("count cars: " & Json_ObjGetCount($aCars) & @CRLF)

    ;Solution from TheDcoder
    Local $aCars = Json_Get($Obj, '["cars"]')
    ConsoleWrite("count cars: " & UBound($aCars) & @CRLF)
    
    ;Walking the array
    For $iCurrentCar = 0 To UBound($aCars) - 1 ;zero-based array
        ConsoleWrite("Car '" & $iCurrentCar & "' of '" & UBound($aCars) & "' is '" & _
            Json_Get($Obj, '["cars"][' & $iCurrentCar & ']') & "'" & @CRLF)
    Next

 

Link to comment
Share on other sites

  • 2 months later...

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...