Что нового

[Сеть, интернет] Разбор JSON-ответа от сервера и получение переменных

Realetive

Новичок
Сообщения
6
Репутация
0
Доброго времени суток. Столкнулся с проблемой — необходимо разобрать полученный в формате JSON ответ от сервера и получить конкретные значения.

Ответ приходит в следующем виде:
Код:
{
 "data": {
  "translations": [
   {
    "translatedText": "Переведи меня",
    "detectedSourceLanguage": "en"
   }
  ]
 }
}

Как получить значения "translatedText" и "detectedSourceLanguage"? Пытался через _JSONDecodeAll(JSON) из JSON UDF Library (www.autoitscript.com/forum/topic/104150-json-udf-library-fully-rfc4627-compliant/), но видимо руки из жопы плохо разобрался со сторонней библиотекой.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: [Сеть, интернет] Разбор JSON

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"[Сеть, интернет] Разбор JSON" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Администратор.
 

focus

Осваивающий
Сообщения
69
Репутация
20
Re: [Сеть, интернет] Разбор JSON

Уменя так получилось. Наверно регулярными проще будет

Код:
#include <String.au3>
#include <Array.au3>

Global $sText = '{"data": {"translations": [{"translatedText": "Переведи меня","detectedSourceLanguage": "en"}]}}'
Global $sS1= '"translatedText":'
Global $sS2 = ','
Global $sS3 = '"detectedSourceLanguage":'
Global $sS4 = '}'

_Main()

Func _Main()
    Local $aArray1 = _StringBetween($sText, $sS1, $sS2)
	Local $aArray2 = _StringBetween($sText, $sS3, $sS4)

    _ArrayDisplay($aArray1, 'Default Search')
	_ArrayDisplay($aArray2, 'Default Search')
EndFunc   ;==>_Main
 

Arei

Скриптер
Сообщения
938
Репутация
115
Re: [Сеть, интернет] Разбор JSON

Если обычно получить данные, то вот вариант
Код:
$w = '{ "data": {"translations": [{"translatedText": "Переведи меня","detectedSourceLanguage": "en"}]}}'
$start='translatedText": "'
$end='",'
$start1='detectedSourceLanguage": "'
$end1='"'
$ww = StringFindSE($w, $start, $end )
$ww1= StringFindSE($w, $start1, $end1 )
MsgBox("","",$ww1)






Func StringFindSE($string, $start = "", $end = "", $start_occ = 1, $end_occ = 1, $cas = 0)
	Local $source_start, $source_count, $source
	If $start <> '' Then
		Local $st_count
		$st_count = StringSplit($start, '')
		$source_start = StringInStr($string, $start, $cas, $start_occ) + $st_count[0]
	Else
		$source_start = 1
	EndIf
	If $end <> '' Then
		$source_count = StringInStr($string, $end, $cas, $end_occ, $source_start) - $source_start
	Else
		$source_count = -1
	EndIf
	Return StringMid($string, $source_start, $source_count)
EndFunc   ;==>StringFindSE
 
Автор
Realetive

Realetive

Новичок
Сообщения
6
Репутация
0
Оба варианта работают, большое спасибо. Надеялся, что есть более нативный способ получения переменных из JSON, как в php, например, но, видимо, действительно, придется использовать банальные регулярки.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
На немецком сайте AutoIt (ссылка на источник) нашел:
Код:
#include <Array.au3>

;Example starts here

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)

$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

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

Как раз демонстрируют такую задачу и в итоге получаем массив.
 
Верх