Vejam se é possivel tirar algo daqui:
/**
* (User) Function: FromJson(cJstr)
* Converts from a JSON string into any value it holds
*
* Example:
* ----
* cJSON := '{"Products": [{"Name": "Water", "Cost": 1.3}, {"Name": "Bread", "Cost": 4e-1}], "Users": [{"Name": "Arthur", "Comment": "Hello\" \\World"}]}'
*
* aaBusiness := FromJson(cJSON)
*
* alert(aaBusiness[#'Products'][1][#'Name']) // Returns -> Water
*
* alert(aaBusiness[#'Products'][2][#'Cost']) // Returns -> 0.4
*
* alert(aaBusiness[#'Users'][1][#'Comment']) // Returns -> Hello" \World
* ----
*
* Additional Info:
* * Numbers accept the Scientific E Notation
* 234e-7 = 0.0000234
* 57e3 = 57000
* * I don't know how I can make an Unicode or UTF-8 character in AdvPL,
* So, the json \uXXXX converts an ASCII code. Values outside the ASCII table becomes '?' (quotation marks).
*
* @param cJstr - The JSON string you want to convert from
* @return - The converted JSON string, it can be any type. Or Nil in case of a bad formatted JSON string.
**/
Function FromJson(cJstr)
Return GetJsonVal(cJstr)[1]
/**
* Internal Function: GetJsonVal(cJstr)
* Converts from a JSON string into any value it holds
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* uVal, - Value of the converted JSON string, or Nil in case of a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function GetJsonVal(cJstr)
Local nConta
Local cLetra := ""
Local aTmp := array(1) // coloquei := {}
BEGIN SEQUENCE
For nConta:= 1 To Len(cJstr)
cLetra := SubStr(cJstr, nConta, 1)
oSay107:SetText( cLetra )
if cLetra == '"'
aTmp := JsonStr(SubStr(cJstr, nConta))
BREAK
elseif at(cLetra, "0123456789.-") > 0
aTmp := JsonNum(SubStr(cJstr, nConta))
BREAK
elseif cLetra == "["
aTmp := JsonArr(SubStr(cJstr, nConta))
BREAK
elseif cLetra == "{"
aTmp := JsonObj(SubStr(cJstr, nConta))
BREAK
elseif at(cLetra, "TtFfNn") > 0 //True, False or Null
aTmp := JsonTFN(SubStr(cJstr, nConta))
BREAK
endif
Next
END SEQUENCE
if len(aTmp) > 0
if aTmp[2] < 0
return {Nil, -1} // Error Code
endif
return {aTmp[1], nConta + aTmp[2] -1}
endif
Return {Nil, -1}
/**
* Internal Function: JsonArr(cJstr)
* Converts from a JSON string containing only an Array into an Array
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* aVal, - Value of the JSON array, or Nil in case of a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function JsonArr(cJstr)
Local nConta
Local cLetra := ""
Local lNeedComma := .F.
Local aRet := {}
Local aTmp := array(1) // coloquei := {}
//BEGIN SEQUENCE
For nConta:= 2 To Len(cJstr)
cLetra := SubStr(cJstr, nConta, 1)
if !lNeedComma .and. at(cLetra, '"{[0123456789.-') > 0
aTmp := GetJsonVal(SubStr(cJstr, nConta))
if aTmp[2] < 0
return {Nil, -1} // Error Code
endif
AADD(aRet, aTmp[1])
nConta := nConta + aTmp[2] -1 // -1 move to last character because the loop will add +1.
lNeedComma := .T.
elseif lNeedComma .and. cLetra == ','
lNeedComma := .F.
elseif cLetra == ']'
return {aRet, nConta}
endif
Next
//END SEQUENCE
Return {Nil, -1}
/**
* Internal Function: JsonObj(cJstr)
* Converts from a JSON string containing only an Object into an Associative Array (SHash Object)
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* aaVal, - Associative Array (SHash Object) of the JSON object, or Nil in case of a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function JsonObj(cJstr)
Local nConta
Local cLetra := ""
Local cTmpStr := ""
Local nStep := 1
Local aTmp := array(1) // coloquei := {}
Local aaRet := array() // array(#) Nao foi aceito
//BEGIN SEQUENCE
For nConta:= 2 To Len(cJstr)
cLetra := SubStr(cJstr, nConta, 1)
if nStep == 1 .and. cLetra == '"'
aTmp := JsonStr(SubStr(cJstr, nConta))
if aTmp[2] < 0
return {Nil, -1} // Error Code
endif
nConta := nConta + aTmp[2] -1
cTmpStr := aTmp[1]
nStep := 2
elseif nStep == 2 .and. cLetra == ':'
nStep := 3
elseif nStep == 3 .and. at(cLetra, '"{[0123456789.-TtFfNn') > 0
aTmp := GetJsonVal(SubStr(cJstr, nConta))
if aTmp[2] < 0
return {Nil, -1} // Error Code
endif
nConta := nConta + aTmp[2] -1
nStep := 4
elseif nStep == 4 .and. cLetra == ','
aaRet[cTmpStr] := aTmp[1] // aaRet[#cTmpStr] := aTmp[1]
nStep := 1
elseif nStep == 4 .and. cLetra == '}'
aaRet[cTmpStr] := aTmp[1] // aaRet[#cTmpStr] := aTmp[1]
return {aaRet, nConta}
endif
Next
//END SEQUENCE
Return {Nil, -1}
/**
* Internal Function: JsonStr(cJstr)
* Converts from a JSON string containing only a String into a String
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* cVal, - Value of the JSON string, or Nil in case of a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function JsonStr(cJstr)
Local nConta
Local cLetra := ""
Local cTmpStr := ""
Local nUnic
//BEGIN SEQUENCE
For nConta:= 2 To Len(cJstr)
cLetra := SubStr(cJstr, nConta, 1)
if cLetra == "\"
nConta++
cLetra := SubStr(cJstr, nConta, 1)
if cLetra == 'b'
cTmpStr += CHR_BS
elseif cLetra == 'f'
cTmpStr += CHR_FF
elseif cLetra == 'n'
cTmpStr += CHR_LF
elseif cLetra == 'r'
cTmpStr += CHR_CR
elseif cLetra == 't'
cTmpStr += CHR_HT
elseif cLetra == 'u'
nUnic := CTON(UPPER(SubStr(cJstr, nConta+1, 4)),16)
if nUnic <= 255
cTmpStr += chr(nUnic)
else
cTmpStr += '?'
endif
nConta += 4
else
cTmpStr += cLetra //it will add the char if it doesn't have a special function
endif
elseif cLetra == '"'
return {cTmpStr, nConta}
else
cTmpStr += cLetra
endif
Next
//END SEQUENCE
Return {Nil, -1}
/**
* Internal Function: JsonNum(cJstr)
* Converts from a JSON string containing only a Number into a Number
* It accepts the (Scientific) E Notation
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* nVal, - Value of the JSON number, or Nil in case of a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function JsonNum(cJstr)
Local nConta, nNum, aTmp := array(1) // coloquei := {}
Local cLetra := ""
Local cTmpStr := ""
Local lNegExp := .F.
//BEGIN SEQUENCE
For nConta:= 1 To Len(cJstr)
cLetra := SubStr(cJstr, nConta, 1)
if at(cLetra, '0123456789.-') > 0
cTmpStr += cLetra
elseif len(cLetra) > 0 .and. UPPER(cLetra) == 'E'
nNum := val(cTmpStr)
cTmpStr := ""
nConta++
cLetra := SubStr(cJstr, nConta, 1)
if cLetra == '-'
lNegExp := .T.
nConta++
elseif cLetra == '+'
nConta++
endif
cLetra := SubStr(cJstr, nConta, 1)
while at(cLetra, '0123456789') > 0
cTmpStr += cLetra
nConta++
cLetra := SubStr(cJstr, nConta, 1)
end
if lNegExp
//nNum := nNum / val('1'+REPLICATE( '0', val(cTmpStr) ))
if val(cTmpStr) != 0
nNum := nNum * val('0.'+REPLICATE( '0', val(cTmpStr)-1) + '1')
endif
else
nNum := nNum * val('1'+REPLICATE( '0', val(cTmpStr) ))
endif
return {nNum, nConta-1}
elseif len(cLetra) > 0
return {val(cTmpStr), nConta-1}
endif
Next
//END SEQUENCE
Return {Nil, -1}
/**
* Internal Function: JsonTFN(cJstr)
* Converts from a JSON string containing only a logical True, False or Null
*
* @param cJstr - The JSON string you want to convert from
* @return array(
* lVal, - Value of the JSON logical value, or Nil in case of Null or a bad formatted JSON string.
* nPos - Position of the last processed character. Returns -1 in case of a bad formatted JSON string.
* )
**/
Static Function JsonTFN(cJstr)
Local cTmpStr
//BEGIN SEQUENCE
cTmpStr := lower(SubStr(cJstr, 1, 5))
if cTmpStr == "false"
return {.F., 5}
endif
cTmpStr := SubStr(cTmpStr, 1, 4)
if cTmpStr == "true"
return {.T., 4}
elseif cTmpStr == "null"
return {Nil, 4}
endif
//END SEQUENCE
Return {Nil, -1}