Что нового

Как сделать проход по объекту, если цикл For In выдает ошибку

alex33

Скриптер
Сообщения
1,457
Репутация
186
Как парсить подобный JSON? А точнее, как лучше работать с такими объектами?
Код:
Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

;////////////////<
Local $oData = _jsonDecode('{' & @LF & _
		'    "status": "OK",' & @LF & _
		'    "status_code": 100,' & @LF & _
		'    "sms": {' & @LF & _
		'        "+790*******7-0": {' & @LF & _
		'            "status": "ERROR",' & @LF & _
		'            "status_code": 202,' & @LF & _
		'            "status_text": "Неправильно указан номер телефона получателя, либо на него нет маршрута"' & @LF & _
		'        },         "+790*******7": {' & @LF & _
		'            "status": "OK",' & @LF & _
		'            "status_code": 100,' & @LF & _
		'            "sms_id": "201749-1000001"' & @LF & _
		'        }, "79*******90": {' & @LF & _
		'"status": "OK",' & @LF & _
		'"status_code": 100,' & @LF & _
		'"sms_id": "000000-10000000"' & @LF & _
		'},' & @LF & _
		'"749******27": {' & @LF & _
		'"status": "ERROR",' & @LF & _
		'"status_code": 207, // Код ошибки' & @LF & _
		'"status_text": "На этот номер (или один из номеров) нельзя отправлять сообщения, либо указано более 100 номеров в списке получателей" // Описание ошибки' & @LF & _
		'}' & @LF & _
		'    },' & @LF & _
		'    "balance": 68.12' & @LF & _
		'}');
;////////////////>

If @error Then Exit 1

If ($oData.status == "OK") Then
	MsgBox(0, "", "Остаток: " & $oData.balance);
	For $phone In $oData.sms ; Член группы не найден. ; =========================
		With (Execute('$oData.sms.' & $phone))
			MsgBox(0, "", "номер: " & $phone & ", статус: " & .status & " " & .status_code);
		EndWith
	Next
EndIf


Func _jsonDecode($sStr)
	Local $__sExecuteCode
	Local $oSC = ObjCreate("ScriptControl")
	If Not IsObj($oSC) Then Return SetError(1, 0, 0)
	$oSC.Language = "JavaScript"
	$sStr = StringReplace($sStr, "\", "\\")
	$sStr = StringReplace($sStr, "'", "\'")
	$sStr = StringRegExpReplace($sStr, '[\r\n]', '\\n')
	$__sExecuteCode = "eval('(" & $sStr & ")');"
	$oResult = $oSC.Eval($__sExecuteCode)
	If Not IsObj($oResult) Then Return SetError(2, 0, 0)
	Return $oResult
EndFunc   ;==>_jsonDecode

Func _ErrFunc($oError)
	ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

Пример на JavaScript, который работает:
* Запустить! *
Код:
try{

////////////////<
var oData = {
    "status": "OK",
    "status_code": 100,
    "sms": {
        "+790*******7-0": {
            "status": "ERROR",
            "status_code": 202,
            "status_text": "Неправильно указан номер телефона получателя, либо на него нет маршрута"
        },         "+790*******7": {
            "status": "OK",
            "status_code": 100,
            "sms_id": "201749-1000001"
        }, "79*******90": {
"status": "OK",
"status_code": 100,
"sms_id": "000000-10000000"
},
"749******27": {
"status": "ERROR",
"status_code": 207, // Код ошибки
"status_text": "На этот номер (или один из номеров) нельзя отправлять сообщения, либо указано более 100 номеров в списке получателей" // Описание ошибки
}
    },
    "balance": 68.12
}
////////////////>

	if ( oData.status == "OK" ) {
		alert( "Остаток: " + oData.balance );
		for ( phone in oData.sms ) {
			with ( oData["sms"][phone] ) {
				alert( "номер: " + phone + ", статус: " + status + " " + status_code );
			}
		}
	}

} catch(er) {
	alert(er.name+" "+er.message+" "+er.stack);
}
 
Автор
alex33

alex33

Скриптер
Сообщения
1,457
Репутация
186
А что, если в функции _jsonDecode заменить самую первую { или самую последнюю } на код со своими функциями и добавить его к передаваемому JSON? Так примерно.
Код:
{ /* ... */
	"getItemByName":function (name) {  return this[name]; },
	"getAllItems":function () {
		/* создать здесь Scripting.Dictionary и через for это все перебрать? */
		var oDict = new ActiveXObject('Scripting.Dictionary');
		oDict.CompareMode = 1;
		for (oTmp in this) {
			oDict.Item( oTmp ) = this[oTmp];
		}
		return oDict;
	}
/* ... */ }
Можно ли так и будет ли это работать?


Добавлено:
Сообщение автоматически объединено:

А, нет. Никак. При добавлении функций в эти данные я получаю 0x8000FFFF Разрушительный сбой! Даже eval убирал и делал просто через переменную. Причём аналогичный код в браузере отрабатывает на ура!
 
Автор
alex33

alex33

Скриптер
Сообщения
1,457
Репутация
186
Так как же лучше сделать? Ни у кого мыслей нет? Или это сделать нельзя и ... снова переходить на парсинг регулярными выражениями?

Слушайте, а нет ли случайно какой-нибудь DLL ки, чтобы можно было удобно все эти вещи проделывать?
Например:
Код:
DllCall("json.dll", "...", "parse", "WSTR", '{"name":"value", "qwerty": "asdf"}')
$a = DllCall("json.dll", "...", "getitem", "WSTR", "name")
     ;     $a[0] = "value"
 

InnI

AutoIT Гуру
Сообщения
4,782
Репутация
1,377
https://www.autoitscript.com/forum/topic/104150-json-udf-library-fully-rfc4627-compliant/
https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn/
https://www.autoitscript.com/forum/topic/156794-oo_jsonudf-jsonpath-oo-using-javascript-in-auto-it/
 
Верх