Hallo,
Wer mal mit Ajax gearbeitet hat, der wird JSON kennen. Wer es nicht kennt:
http://de.wikipedia.org/wiki/JavaScrip…ormatdefinition
Wenn man mit AutoIt mal so einen JSON String auswerten möchte, der kommt um StringRegExp nicht herum. Und selbst damit ist es manchmal sehr nervenaufreibend.
Denn ein üblicher JSON String sieht ungefähr so aus:
{"Herausgeber": "Xema","Nummer": "1234-5678-9012-3456","Deckung": 2e+6,"Währung": "EURO","Inhaber": {"Name": "Reich","Vorname": "Rainer","männlich": true,"Hobbys": [ "Reiten", "Golfen", "Lesen" ],"Alter": 42,"SozialesGewissen": null}"Firma": "Abc-Firma","Standort": ["Am Gewerbegebiet 25", "Etage 2"]}
Nur halt viieeeeel länger.
Ich bruachte jedenfalls eine Funktion um einen JSON String in AutoIt zu verwerten, weil ich mit RegExp gescheitert bin.
Das ganze funktioniert natürlich rekursiv (wie auch sonst).
Zurückgegeben wird ein 2 Dimensionaler Array, welcher das Hauptobjekt repräsentiert, in dem [n][0] der Schlüssel und [n][1] der Wert ist.
Der Schlüssel ist eine Zeichenkette. Der Wert enthält entweder eine Zeichenkette (oder Float), ein Objekt oder einen Array. Ein Array wird als 1D Array (im Array) eingebunden.
Der Funktion liegt auch ein Beispiel bei.
Spoiler anzeigen
#include <Array.au3>
;Example starts here
[/autoit] [autoit][/autoit] [autoit]Local $aReturn, $aInhaber, $aHobbies, $aStandort, $sText
$sText = _
'{' & @CRLF & _
' "Herausgeber": "Xema",' & @CRLF & _
' "Nummer": "1234-5678-9012-3456",' & @CRLF & _
' "Deckung": 2e+6,' & @CRLF & _
' "Währung": "EURO",' & @CRLF & _
' "Inhaber": {' & @CRLF & _
' "Name": "Reich",' & @CRLF & _
' "Vorname": "Rainer",' & @CRLF & _
' "männlich": true,' & @CRLF & _
' "Hobbys": [ "Reiten", "Golfen", "Lesen" ],' & @CRLF & _
' "Alter": 42,' & @CRLF & _
' "SozialesGewissen": null' & @CRLF & _
' }' & @CRLF & _
' "Firma": "Abc-Firma",' & @CRLF & _
' "Standort": ["Am Gewerbegebiet 25", "Etage 2"]' & @CRLF & _
'}' & @CRLF
$aReturn = _JSON_Decode($sText)
[/autoit] [autoit][/autoit] [autoit]$aInhaber = $aReturn[4][1] ; Child Array
$aHobbies = $aInhaber[3][1] ; Child Array from $aInhaber
$aStandort = $aReturn[6][1] ; Child Array
_ArrayDisplay($aReturn, "Hauptobjekt")
_ArrayDisplay($aInhaber, "Inhaber")
_ArrayDisplay($aHobbies, "Hobbies")
_ArrayDisplay($aReturn, "Hauptobjekt")
_ArrayDisplay($aStandort, "Standort")
$sEncoded = _JSON_Encode($aReturn)
MsgBox(0,"",$sEncoded)
;Functions start here
[/autoit] [autoit][/autoit] [autoit]Func _JSON_Decode($sString)
Local $iIndex, $aVal, $sOldStr = $sString, $b
$sString = StringStripCR(StringStripWS($sString, 7))
If Not StringRegExp($sString, "(?i)^\{.+}$") Then Return SetError(1, 0, 0)
Local $aArray[1][2], $iIndex = 0
$sString = StringMid($sString, 2)
Do
$b = False
$aVal = StringRegExp($sString, '^"([^"]+)"\s*:\s*(["{[]|[-+]?\d+(?:(?:\.\d+)?[eE][+-]\d+)?|true|false|null)', 2) ; Get value & next token
If @error Then
ConsoleWrite("!> StringRegExp Error getting next Value." & @CRLF)
ConsoleWrite($sString & @CRLF)
$sString = StringMid($sString, 2) ; maybe it works when the string is trimmed by 1 char from the left ?
ContinueLoop
EndIf
$aArray[$iIndex][0] = $aVal[1] ; Key
$sString = StringMid($sString, StringLen($aVal[0]))
Switch $aVal[2] ; Value Type (Array, Object, String) ?
Case '"' ; String
; Value -> Array subscript. Trim String after that.
$aArray[$iIndex][1] = StringMid($sString, 2, StringInStr($sString, """", 1, 2) - 2)
$sString = StringMid($sString, StringLen($aArray[$iIndex][1]) + 3)
ReDim $aArray[$iIndex + 2][2]
$iIndex += 1
Case '{' ; Object
; Recursive function call which will decode the object and return it.
; Object -> Array subscript. Trim String after that.
$aArray[$iIndex][1] = _JSON_Decode($sString)
$sString = StringMid($sString, @extended + 2)
If StringLeft($sString, 1) = "," Then $sString = StringMid($sString, 2)
$b = True
ReDim $aArray[$iIndex + 2][2]
$iIndex += 1
Case '[' ; Array
; Decode Array
$sString = StringMid($sString, 2)
Local $aRet[1], $iArIndex = 0 ; create new array which will contain the Json-Array.
Do
$sString = StringStripWS($sString, 3) ; Trim Leading & trailing spaces
$aNextArrayVal = StringRegExp($sString, '^\s*(["{[]|\d+(?:(?:\.\d+)?[eE]\+\d+)?|true|false|null)', 2)
Switch $aNextArrayVal[1]
Case '"' ; String
; Value -> Array subscript. Trim String after that.
$aRet[$iArIndex] = StringMid($sString, 2, StringInStr($sString, """", 1, 2) - 2)
$sString = StringMid($sString, StringLen($aRet[$iArIndex]) + 3)
Case "{" ; Object
; Recursive function call which will decode the object and return it.
; Object -> Array subscript. Trim String after that.
$aRet[$iArIndex] = _JSON_Decode($sString)
$sString = StringMid($sString, @extended + 2)
Case "["
MsgBox(0, "", "Array in Array. WTF is up with this JSON shit?")
MsgBox(0, "", "This should not happen! Please post this!")
Exit 0xDEADBEEF
Case Else
ConsoleWrite("Array Else (maybe buggy?)" & @CRLF)
$aRet[$iArIndex] = $aNextArrayVal[1]
EndSwitch
ReDim $aRet[$iArIndex + 2]
$iArIndex += 1
$sString = StringStripWS($sString, 3) ; Leading & trailing
If StringLeft($sString, 1) = "]" Then ExitLoop
$sString = StringMid($sString, 2)
Until False
$sString = StringMid($sString, 2)
ReDim $aRet[$iArIndex]
$aArray[$iIndex][1] = $aRet
ReDim $aArray[$iIndex + 2][2]
$iIndex += 1
Case Else ; Number, bool
; Value (number (int/flaot), boolean, null) -> Array subscript. Trim String after that.
$aArray[$iIndex][1] = $aVal[2]
ReDim $aArray[$iIndex + 2][2]
$iIndex += 1
$sString = StringMid($sString, StringLen($aArray[$iIndex][1]) + 2)
EndSwitch
If StringLeft($sString, 1) = "}" Then
StringMid($sString, 2)
ExitLoop
EndIf
If Not $b Then $sString = StringMid($sString, 2)
Until False
ReDim $aArray[$iIndex][2]
Return SetError(0, StringLen($sOldStr) - StringLen($sString), $aArray)
EndFunc ;==>_JSON_Decode
Func _JSON_Encode($aArray)
Local $sString, $iDim = UBound($aArray, 0), $iUB, $iUB_2
Switch $iDim ; What type of Property?
Case 2 ; Object
$sString = "{"
$iUB = UBound($aArray)
$iUB_2 = UBound($aArray,2)
For $i = 0 To $iUB-1
$sString &= '"' & $aArray[$i][0] & '":'
If IsArray($aArray[$i][1]) Then
$sString &= _JSON_Encode($aArray[$i][1])
Else
$sString &= '"' & $aArray[$i][1] & '"'
EndIf
$sString &= ","
Next
$sString = StringTrimRight($sString, 1) & "}"
Case 1 ; Array
$sString = "["
$iUB = UBound($aArray)
For $i = 0 To $iUB - 1
If IsArray($aArray[$i]) Then
$sString &= _JSON_Encode($aArray[$i])
Else
$sString &= '"' & $aArray[$i] & '"'
EndIf
$sString &= ","
Next
$sString = StringTrimRight($sString, 1) & "]"
Case Else
Return SetError(1, 0, "")
EndSwitch
Return $sString
EndFunc ;==>_JSON_Encode