Pour travailler avec des fichiers JSON, AGS fournit le wrapper @autoit-gui-skeleton/ags-wrapper-json de la librairie JSON.au3, créé par Ward. Cette librairie nous permet de décoder / encoder en JSON en utilisant l’analyseur jsmn.
Comment installer AGS-wrapper-json ?
On suppose que vous avez déjà installé Node.js et Yarn, par example avec Chocolatey, et pour installer le package AGS-wrapper-json, vous pouvez alors utiliser le gestionnaire de dépendances pour AutoIt fournit dans AGS. Il suffit donc de taper dans le dossier racine du projet, où le fichier package.json
est stocké:
yarn add @autoit-gui-skeleton/ags-wrapper-json --modules-folder vendor
Toutes les dépendances du projet, ainsi que les dépendances filles des dépedances parentes sont installées dans le répertoire ./vendor/@autoit-gui-skeleton/
. Pour l’utiliser dans son programme AutoIt, vous devez inclure cette bibliothèque avec l’instruction:
#include 'vendor/@autoit-gui-skeleton/ags-wrapper-json/JSON.au3'
Tous les paquets AGS hébergés dans le dépôt npmjs appartiennent à l’organisation @autoit-gui-skeleton organization. En effet afin de simplifier la gestion des dépendances d’un projet AutoIt construit avec le framework AGS, nous avons détourné de son utilisation initiale le gestionnaire de dépendance npm, et son évolution Yarn. Cela nous permet de gérer les dépendances d’un projet AGS avec d’autres bibliothèques AutoIt, et de partager ces paquets AutoIt à partir du référentiel npmjs.org.
Comment décoder un JSON ?
Décoder depuis un fichier JSON local
Par exemple, crééz ce fichier json dans le répertoire ./assets/DROIDS.json
de votre projet AGS.
{
"project": "Listing droids",
"version": "1.0",
"author": {
"name": "Luke",
"mail": "luke@2080.org"
},
"droids": [
{
"name": "R2D2",
"type": "Astromecano",
"size": "0,96m"
},
{
"name": "BB8",
"type": "Astromecano",
"size": "0,67m"
},
{
"name": "C-3PO",
"type": "Social",
"size": "1,67m"
}
]
}
Pour décoder ce fichier, on utilise la fonction suivante json_decode_from_file
.
#include 'vendor/@autoit-gui-skeleton/ags-wrapper-json/JSON.au3'
;====================================================================================
; Decode JSON from a given local file
;
; @param $jsonfilePath (string)
; @return $object (object), instance return by json_decode
;====================================================================================
Func json_decode_from_file($filePath)
Local $fileOpen, $fileContent, $object
$fileOpen = FileOpen($filePath, $FO_READ)
If $fileOpen = -1 Then
Return SetError(1, 0, "An error occurred when reading the file " & $filePath)
EndIf
$fileContent = FileRead($fileOpen)
FileClose($fileOpen)
$object = Json_Decode($fileContent)
Return $object
EndFunc
Selon la documentation de Ward:
The most JSON data type will be decoded into corresponding AutoIt variable, including 1D array, string, number, true, false, and null. JSON object will be decoded into “Windows Scripting Dictionary Object” retuned from
ObjCreate("Scripting.Dictionary")
. AutoIt build-in functions like IsArray, IsBool, etc. can be used to check the returned data type. But for Object and Null, Json_IsObject() and Json_IsNull() should be used.
If the input JSON string is invalid,
@Error
will be set to$JSMN_ERROR_INVAL
. And if the input JSON string is not finish,@Error
will be set to$JSMN_ERROR_PART
.
Obtenir la valeur à partir d’un objet JSON
Pour utiliser $jsonObject
, le retour de json_decode_from_file
, vous pouvez utilsier la fonction Json_Get
. Pour sélectionner une variable JSON, vous pouvez utiliser au choix la notation par point ou par crochet.
Local $file = @ScriptDir & "\assets\DROIDS.json"
Local $jsonObject = json_decode_from_file($file)
; With dot notation
Local $project = Json_Get($jsonObject, '.project') ; Listing droids
Local $name = Json_Get($jsonObject, '.author.name') ; Luke
Local $mail = Json_Get($jsonObject, '.author.mail') ; luke@2080.org
local $test = Json_Get($jsonObject, '.droids[1].name') ; BB8
; With array notation
Local $project2 = Json_Get($jsonObject, '["project"]')
Local $name2 = Json_Get($jsonObject, '["author"]["name"]')
Local $mail2 = Json_Get($jsonObject, '["author"]["mail"]')
local $test2 = Json_Get($jsonObject, '["droids"][1]["name"]')
Vous pouvez également utiliser des fonctions d’aide, qui son des couches d’abtractions des fonctions de Scripting.Dictionary
COM object.
- Json_ObjCreate()
- Json_ObjPut(ByRef $Object, $Key, $Value)
- Json_ObjGet(ByRef $Object, $Key)
- Json_ObjDelete(ByRef $Object, $Key)
- Json_ObjExists(ByRef $Object, $Key)
- Json_ObjGetCount(ByRef $Object)
- Json_ObjGetKeys(ByRef $Object)
- Json_ObjClear(ByRef $Object)
Travailler avec une collection d’objet et parcourir ses éléments
Pour itérer les valeurs d’un tableau json:
Local $file = @ScriptDir & "\assets\DROIDS.json"
Local $jsonObject = json_decode_from_file($file)
; Check if exists an item droid into the collection `droids`
Local $droids = Json_Get($jsonObject, '.droids')
If UBound($droids) = 0 Then
Return SetError(3, 0, "Array attribute 'droids' is empty.")
EndIf
; Iterate items collection to store values into an array
Local $array[UBound($droids)][3]
For $i = 0 To UBound($droids) - 1 Step 1
$array[$i][0] = Json_Get($jsonObject, '.droids' & '[' & $i & '].name')
$array[$i][1] = Json_Get($jsonObject, '.droids' & '[' & $i & '].type')
$array[$i][2] = Json_Get($jsonObject, '.droids' & '[' & $i & '].size')
Next
Ajouter un objet dans un JSON
Vous pouvez le faire simplement avec la fonction Json_Put
:
Local $Obj
Json_Put($Obj, ".foo", "foo")
Json_Put($Obj, ".bar[0]", "bar")
Json_Put($Obj, ".test[1].foo.bar[2].foo.bar", "Test")
Local $Test = Json_Get($Obj, '["test"][1]["foo"]["bar"][2]["foo"]["bar"]') ; "Test"
Décoder un fichier JSON depuis un serveur distant
Pour décoder un fichier JSON hébergé sur un serveur distant, ou qui se construit depuis un webservice ou encore à partir d’une API Rest, vous pouvez utiliser @autoit-gui-skeleton/ags-component-http-request pour effectuer des requetes HTTP vers une URL donnée.
#include 'vendor/@autoit-gui-skeleton/ags-component-http-request/ags-component-http-request.au3'
;====================================================================================
; Decode JSON from a given URL
;
; @param $jsonfileUrl (string)
; @param $proxy (string), by default we load proxy settings form configuration file
; @return $object (object), instance return by json_decode
;====================================================================================
Func json_decode_from_url($jsonfileUrl, $proxy = "")
Local $response = HttpGET($jsonfileUrl, Default, $proxy)
If (@error) Then
Return SetError(@error, $response, _
"Unable to get json file on server " & $jsonfileUrl & ".")
EndIf
Local $data = $response.ResponseText
Local $object = json_decode($data)
Return $object
EndFunc
Local $jsonObject = json_decode_from_url(https://api.spacexdata.com/v2/info)
Local $name = Json_Get($jsonObject, '.name') ; SpaceX
Local $founder = Json_Get($jsonObject, '.founder') ; Elon Musk
Local $founded = Json_Get($jsonObject, '.founded') ; 2002
Comment encoder un JSON ?
Selon la documentation de Ward’s, vous pouvez utilsier Json_Encode($Data, $Option = 0, $Indent = "\t", $ArraySep = ",\r\n", $ObjectSep = ",\r\n", $ColonSep = ": ")
.
$Data
can be a string, number, bool, keyword : default or null, 1D array, orScripting.Dictionary
COM object.- Binary will be converted to string in UTF8 encoding.
- Ptr will be converted to number
- Other unsupported types like 2D array, dllstruct or object will be encoded into null.
$Option
is bitmask consisting following constant:
$JSON_UNESCAPED_ASCII
; Don’t escape ascii charcters between chr(1) ~ chr(0x1f)$JSON_UNESCAPED_UNICODE
; Encode multibyte Unicode characters literally$JSON_UNESCAPED_SLASHES
; Don’t escape /$JSON_HEX_TAG
; All < and > are converted to \u003C and \u003E$JSON_HEX_AMP
; All &amp;amp;s are converted to \u0026$JSON_HEX_APOS
; All ‘ are converted to \u0027$JSON_HEX_QUOT
; All “ are converted to \u0022$JSON_PRETTY_PRINT
; Use whitespace in returned data to format it$JSON_STRICT_PRINT
; Make sure returned JSON string is RFC4627 compliant$JSON_UNQUOTED_STRING
; Output unquoted string if possible (conflicting with $JSMN_STRICT_PRINT)
Par exemple pour encoder en JSON:
Local $file = @ScriptDir & "\assets\DROIDS.json"
Local $jsonObject = json_decode_from_file($file)
Local $jsonEncoded = Json_Encode($jsonObject, $JSON_PRETTY_PRINT)
ConsoleWrite($jsonEncoded)
Most encoding option have the same means like PHP’s json_encode() function. When
$JSON_PRETTY_PRINT
is set, output format can be change by other 4 parameters :($Indent, $ArraySep, $ObjectSep, $ColonSep)
. Because these 4 output format parameters will be checked insideJsmn_Encode()
function, returned string will be always accepted byJsmn_Decode()
. $JSON_UNQUOTED_STRING can be used to output unquoted string that also accetped by Jsmn_Decode().$JSON_STRICT_PRINT
is used to check output format setting and avoid non-standard JSON output. So this option is conflicting with$JSON_UNQUOTED_STRING
.
Continuer la lecture ?
https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/