L'utilisation de données au format JSON (JavaScript Object Notation – Notation Objet issue de JavaScript) avec un formatage déterminé à l'avance, est très simple en WLangage, grâce au principe de sérialisation. En effet les fonctions Désérialise et Sérialise permettent de transférer les données JSON dans des structures et/ou tableaux WLangage, qui permettent ensuite toutes les actions possibles.
Par contre lorsqu'une application, ou un site, doit exploiter des données JSON dont le format et les clés ne sont pas connus à l'avance, ou que le format va très probablement être changé, l'utilisation de structures alimentées par la fonction Désérialise n'est plus possible. Dans ce cas, il faut parcourir l'ensemble de la structure afin d'obtenir les différentes clés et leurs valeurs, ainsi que l'arborescence. Pour ce besoin le WLangage propose également une fonction qui fait l'essentiel du travail : JSONVersVariant. Combinée avec la propriété ..Membre, la fonction JSONVersVariant permet en effet un parcours simple d'un JSON d'une structure quelconque, via le type variant.
Voici un exemple de parcours générique, il peut être testé par un copier/coller dans le code d'un bouton par exemple. Il montre comment effectuer le parcours en faisant une "Trace" des clés et valeurs du JSON. Dans la pratique la trace peut être remplacée par tout type d'action en fonction des besoins :
- chargement d'un tableau associatif en utilisant les clés du JSON comme indices pour le tableau
- écriture des données dans une base ...
sJSon est une chaîne= [
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}]}}}
] // exemple de http://json.org/example
vJSON est un Variant = JSONVersVariant(sJSon)
ParcoursMembresVariant(vJSON)
Procedure INTERNE ParcoursMembresVariant(_ObjetOuTableau)
SELON _ObjetOuTableau..Type
CAS wlVariantObjet :
POUR TOUT _Membre DE _ObjetOuTableau..Membre
SI _Membre..Membre..Occurrence=0ALORS
SELON _Membre..Type
CAS wlVariantTableau :
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+...
" contient un tableau...")
ParcoursMembresVariant(_Membre)
AUTRES CAS:
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+" a la valeur "+...
_Membre..Valeur)
FIN
SINON
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+" a "+...
_Membre..Membre..Occurrence+" autres membres...")
ParcoursMembresVariant(_Membre)
FIN
FIN
CAS wlVariantTableau :
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Tableau de "+_ObjetOuTableau..Occurrence+" éléments...")
POUR TOUT ELEMENT UnElement, Compteur DE _ObjetOuTableau
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Exploration de l'élément "+Compteur+"/"+_ObjetOuTableau..Occurrence)
ParcoursMembresVariant(UnElement)
FIN
AUTRES CAS:Trace("A gérer ("+_ObjetOuTableau..Type+") !?"+_ObjetOuTableau)
FIN
FIN
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}]}}}
] // exemple de http://json.org/example
vJSON est un Variant = JSONVersVariant(sJSon)
ParcoursMembresVariant(vJSON)
Procedure INTERNE ParcoursMembresVariant(_ObjetOuTableau)
SELON _ObjetOuTableau..Type
CAS wlVariantObjet :
POUR TOUT _Membre DE _ObjetOuTableau..Membre
SI _Membre..Membre..Occurrence=0ALORS
SELON _Membre..Type
CAS wlVariantTableau :
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+...
" contient un tableau...")
ParcoursMembresVariant(_Membre)
AUTRES CAS:
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+" a la valeur "+...
_Membre..Valeur)
FIN
SINON
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Le membre "+ _Membre..Nom+" a "+...
_Membre..Membre..Occurrence+" autres membres...")
ParcoursMembresVariant(_Membre)
FIN
FIN
CAS wlVariantTableau :
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Tableau de "+_ObjetOuTableau..Occurrence+" éléments...")
POUR TOUT ELEMENT UnElement, Compteur DE _ObjetOuTableau
Trace(Répète("--",ChaîneOccurrence(dbgInfo(dbgPile),RC)) +...
"Exploration de l'élément "+Compteur+"/"+_ObjetOuTableau..Occurrence)
ParcoursMembresVariant(UnElement)
FIN
AUTRES CAS:Trace("A gérer ("+_ObjetOuTableau..Type+") !?"+_ObjetOuTableau)
FIN
FIN
A noter que le code utilise une procédure interne. Elles sont très pratique lorsqu'un code à besoin d'une procédure qui lui est dédiée (récursivité comme ici, et les fonctions WLangage utilisant une "callback"). Elles évitent la création d'une procédure locale à la fenêtre. De plus lorsque le code est copié/collé, la procédure interne l'est également.