Getting data from JSON file with VizScript

ruimac

Active member
If I have a JSON file with the following structure:

{
"owner": "IPMA",
"country": "PT",
"data": [
{
"tMin": "16",
"cityName": "Hong Kong",
"tMax": "21",
"idWeatherType": 3,
"longitude": "114.1744",
"cityId": 1,
"idWeatherTypeDescription": "Ceu limpo, alternando com periodos de pouco nublado",
"latitude": "22.3023"
},
{
"tMin": "8",
"cityName": "Lisboa",
"tMax": "15",
"idWeatherType": 10,
"longitude": "-9.1500",
"cityId": 2,
"idWeatherTypeDescription": "Chuva fraca",
"latitude": "38.7200"
},
{
"cityId": 7,
"cityName": "Antananarivo",
"idWeatherType": 2,
"idWeatherTypeDescription": "Ceu temporariamente muito nublado",
"latitude": "-18.8000",
"longitude": "47.4800",
"tMax": "28",
"tMin": "17"
}
}


How can I go through all the elements of the array and, from each one, read any of the items?
I don't have any GetArray or GetObject functions.
I know I can get a new json object with the At function, but how can I direct it to the array elements?
 

Thank you, Lars. I had already been in thar thread. And pre-processing the JSON files outside is not an option, in my case.
VizScript implementation of the JSON object is not very good and should include a few more functions and commands. As it is now, it doesn't allow for parsing of all JSON files.
In my case, I had to read the JSON file as a text file and parsed it myself, using String functions and commands.
 
It is, in fact a very smart solution, but we would have to install the plugin in all engines in the TV station, and the guys that deal with that are extremelly reluctant in adding non-native Viz plugins. This should really be something that VizScript would deal natively.
 
In Viz there is no GetArray() or GetObject(). Everything is just Json, so:

j["data"] → gives you the array
Size → how many items
At(i) → item at index

That's it:
Code:
Dim dataArray As Json
dataArray = j["data"]

Dim i As Integer
For i = 0 To dataArray.Size - 1
    Dim item As Json
    item = dataArray.At(i)
    Println item.GetString("cityName")
Next

Also btw your JSON is missing the closing ] and }, so it's not valid 🙂

Test:
Code:
Dim j As Json
Dim jstr As String

Structure WeatherItem
    cityName As String
    cityId As Integer
    tMin As Integer
    tMax As Integer
    weatherType As Integer
    description As String
    latitude As Double
    longitude As Double
End Structure

Sub OnInit()

    jstr = "{"
    jstr &= "\"owner\": \"IPMA\","
    jstr &= "\"country\": \"PT\","
    jstr &= "\"data\": ["

    jstr &= "{"
    jstr &= "\"tMin\": \"16\","
    jstr &= "\"cityName\": \"Hong Kong\","
    jstr &= "\"tMax\": \"21\","
    jstr &= "\"idWeatherType\": 3,"
    jstr &= "\"longitude\": \"114.1744\","
    jstr &= "\"cityId\": 1,"
    jstr &= "\"idWeatherTypeDescription\": \"Ceu limpo, alternando com periodos de pouco nublado\","
    jstr &= "\"latitude\": \"22.3023\""
    jstr &= "},"

    jstr &= "{"
    jstr &= "\"tMin\": \"8\","
    jstr &= "\"cityName\": \"Lisboa\","
    jstr &= "\"tMax\": \"15\","
    jstr &= "\"idWeatherType\": 10,"
    jstr &= "\"longitude\": \"-9.1500\","
    jstr &= "\"cityId\": 2,"
    jstr &= "\"idWeatherTypeDescription\": \"Chuva fraca\","
    jstr &= "\"latitude\": \"38.7200\""
    jstr &= "},"

    jstr &= "{"
    jstr &= "\"cityId\": 7,"
    jstr &= "\"cityName\": \"Antananarivo\","
    jstr &= "\"idWeatherType\": 2,"
    jstr &= "\"idWeatherTypeDescription\": \"Ceu temporariamente muito nublado\","
    jstr &= "\"latitude\": \"-18.8000\","
    jstr &= "\"longitude\": \"47.4800\","
    jstr &= "\"tMax\": \"28\","
    jstr &= "\"tMin\": \"17\""
    jstr &= "}"

    jstr &= "]"
    jstr &= "}"

    If Not j.Load(jstr) Then
        Println "ERROR: JSON load failed"
        Exit Sub
    End If

    If Not j.IsObject() Then
        Println "ERROR: root is not object"
        Exit Sub
    End If

    Println "Owner: " & SafeGetString(j, "owner", "")
    Println "Country: " & SafeGetString(j, "country", "")

    Dim dataArray As Json
    dataArray = j["data"]

    If Not dataArray.IsArray() Then
        Println "ERROR: data is not array"
        Exit Sub
    End If

    Dim items As Array[WeatherItem]

    Dim i As Integer
    For i = 0 To dataArray.Size - 1

        Dim itemJson As Json
        itemJson = dataArray.At(i)

        If itemJson.IsObject() Then

            Dim w As WeatherItem
            w = ParseWeatherItem(itemJson)

            items.Push(w)

            Println "----------------------"
            Println "City: " & w.cityName
            Println "City ID: " & w.cityId
            Println "Temp: " & w.tMin & " - " & w.tMax
            Println "Weather ID: " & w.weatherType
            Println "Weather: " & w.description
            Println "Latitude: " & w.latitude
            Println "Longitude: " & w.longitude

        Else
            Println "WARNING: item is not object"
        End If

    Next

End Sub


Function ParseWeatherItem(j As Json) As WeatherItem

    Dim w As WeatherItem

    w.cityName = SafeGetString(j, "cityName", "N/A")
    w.cityId = SafeGetInt(j, "cityId", -1)
    w.tMin = SafeGetInt(j, "tMin", 0)
    w.tMax = SafeGetInt(j, "tMax", 0)
    w.weatherType = SafeGetInt(j, "idWeatherType", -1)
    w.description = SafeGetString(j, "idWeatherTypeDescription", "")
    w.latitude = SafeGetDouble(j, "latitude", 0.0)
    w.longitude = SafeGetDouble(j, "longitude", 0.0)

    ParseWeatherItem = w

End Function


Function SafeGetString(j As Json, key As String, def As String) As String

    Dim v As Json
    v = j[key]

    If v.IsString() Then
        SafeGetString = v.ToString()
    Else
        SafeGetString = def
    End If

End Function

Function SafeGetInt(j As Json, key As String, def As Integer) As Integer

    Dim v As Json
    v = j[key]

    If v.IsInteger() Then
        SafeGetInt = v.ToInteger()

    ElseIf v.IsDouble() Then
        SafeGetInt = CInt(v.ToDouble())

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = v.ToString()

        If tmp = "" Then
            SafeGetInt = def
        Else
            SafeGetInt = CInt(tmp)
        End If

    Else
        SafeGetInt = def
    End If

End Function

Function SafeGetDouble(j As Json, key As String, def As Double) As Double

    Dim v As Json
    v = j[key]

    If v.IsDouble() Then
        SafeGetDouble = v.ToDouble()

    ElseIf v.IsInteger() Then
        SafeGetDouble = CDbl(v.ToInteger())

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = v.ToString()

        If tmp = "" Then
            SafeGetDouble = def
        Else
            SafeGetDouble = CDbl(tmp)
        End If

    Else
        SafeGetDouble = def
    End If

End Function

Function SafeGetBoolean(j As Json, key As String, def As Boolean) As Boolean

    Dim v As Json
    v = j[key]

    If v.IsBoolean() Then
        SafeGetBoolean = j.GetBoolean(key)

    ElseIf v.IsInteger() Then
        SafeGetBoolean = (j.GetInteger(key) <> 0)

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = j.GetString(key)

        If tmp = "true" OR tmp = "True" OR tmp = "1" Then
            SafeGetBoolean = True
        ElseIf tmp = "false" OR tmp = "False" OR tmp = "0" Then
            SafeGetBoolean = False
        Else
            SafeGetBoolean = def
        End If

    Else
        SafeGetBoolean = def
    End If

End Function

End Function

console.jpg
 
In Viz there is no GetArray() or GetObject(). Everything is just Json, so:

j["data"] → gives you the array
Size → how many items
At(i) → item at index

That's it:
Code:
Dim dataArray As Json
dataArray = j["data"]

Dim i As Integer
For i = 0 To dataArray.Size - 1
    Dim item As Json
    item = dataArray.At(i)
    Println item.GetString("cityName")
Next

Also btw your JSON is missing the closing ] and }, so it's not valid 🙂

Test:
Code:
Dim j As Json
Dim jstr As String

Structure WeatherItem
    cityName As String
    cityId As Integer
    tMin As Integer
    tMax As Integer
    weatherType As Integer
    description As String
    latitude As Double
    longitude As Double
End Structure

Sub OnInit()

    jstr = "{"
    jstr &= "\"owner\": \"IPMA\","
    jstr &= "\"country\": \"PT\","
    jstr &= "\"data\": ["

    jstr &= "{"
    jstr &= "\"tMin\": \"16\","
    jstr &= "\"cityName\": \"Hong Kong\","
    jstr &= "\"tMax\": \"21\","
    jstr &= "\"idWeatherType\": 3,"
    jstr &= "\"longitude\": \"114.1744\","
    jstr &= "\"cityId\": 1,"
    jstr &= "\"idWeatherTypeDescription\": \"Ceu limpo, alternando com periodos de pouco nublado\","
    jstr &= "\"latitude\": \"22.3023\""
    jstr &= "},"

    jstr &= "{"
    jstr &= "\"tMin\": \"8\","
    jstr &= "\"cityName\": \"Lisboa\","
    jstr &= "\"tMax\": \"15\","
    jstr &= "\"idWeatherType\": 10,"
    jstr &= "\"longitude\": \"-9.1500\","
    jstr &= "\"cityId\": 2,"
    jstr &= "\"idWeatherTypeDescription\": \"Chuva fraca\","
    jstr &= "\"latitude\": \"38.7200\""
    jstr &= "},"

    jstr &= "{"
    jstr &= "\"cityId\": 7,"
    jstr &= "\"cityName\": \"Antananarivo\","
    jstr &= "\"idWeatherType\": 2,"
    jstr &= "\"idWeatherTypeDescription\": \"Ceu temporariamente muito nublado\","
    jstr &= "\"latitude\": \"-18.8000\","
    jstr &= "\"longitude\": \"47.4800\","
    jstr &= "\"tMax\": \"28\","
    jstr &= "\"tMin\": \"17\""
    jstr &= "}"

    jstr &= "]"
    jstr &= "}"

    If Not j.Load(jstr) Then
        Println "ERROR: JSON load failed"
        Exit Sub
    End If

    If Not j.IsObject() Then
        Println "ERROR: root is not object"
        Exit Sub
    End If

    Println "Owner: " & SafeGetString(j, "owner", "")
    Println "Country: " & SafeGetString(j, "country", "")

    Dim dataArray As Json
    dataArray = j["data"]

    If Not dataArray.IsArray() Then
        Println "ERROR: data is not array"
        Exit Sub
    End If

    Dim items As Array[WeatherItem]

    Dim i As Integer
    For i = 0 To dataArray.Size - 1

        Dim itemJson As Json
        itemJson = dataArray.At(i)

        If itemJson.IsObject() Then

            Dim w As WeatherItem
            w = ParseWeatherItem(itemJson)

            items.Push(w)

            Println "----------------------"
            Println "City: " & w.cityName
            Println "City ID: " & w.cityId
            Println "Temp: " & w.tMin & " - " & w.tMax
            Println "Weather ID: " & w.weatherType
            Println "Weather: " & w.description
            Println "Latitude: " & w.latitude
            Println "Longitude: " & w.longitude

        Else
            Println "WARNING: item is not object"
        End If

    Next

End Sub


Function ParseWeatherItem(j As Json) As WeatherItem

    Dim w As WeatherItem

    w.cityName = SafeGetString(j, "cityName", "N/A")
    w.cityId = SafeGetInt(j, "cityId", -1)
    w.tMin = SafeGetInt(j, "tMin", 0)
    w.tMax = SafeGetInt(j, "tMax", 0)
    w.weatherType = SafeGetInt(j, "idWeatherType", -1)
    w.description = SafeGetString(j, "idWeatherTypeDescription", "")
    w.latitude = SafeGetDouble(j, "latitude", 0.0)
    w.longitude = SafeGetDouble(j, "longitude", 0.0)

    ParseWeatherItem = w

End Function


Function SafeGetString(j As Json, key As String, def As String) As String

    Dim v As Json
    v = j[key]

    If v.IsString() Then
        SafeGetString = v.ToString()
    Else
        SafeGetString = def
    End If

End Function

Function SafeGetInt(j As Json, key As String, def As Integer) As Integer

    Dim v As Json
    v = j[key]

    If v.IsInteger() Then
        SafeGetInt = v.ToInteger()

    ElseIf v.IsDouble() Then
        SafeGetInt = CInt(v.ToDouble())

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = v.ToString()

        If tmp = "" Then
            SafeGetInt = def
        Else
            SafeGetInt = CInt(tmp)
        End If

    Else
        SafeGetInt = def
    End If

End Function

Function SafeGetDouble(j As Json, key As String, def As Double) As Double

    Dim v As Json
    v = j[key]

    If v.IsDouble() Then
        SafeGetDouble = v.ToDouble()

    ElseIf v.IsInteger() Then
        SafeGetDouble = CDbl(v.ToInteger())

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = v.ToString()

        If tmp = "" Then
            SafeGetDouble = def
        Else
            SafeGetDouble = CDbl(tmp)
        End If

    Else
        SafeGetDouble = def
    End If

End Function

Function SafeGetBoolean(j As Json, key As String, def As Boolean) As Boolean

    Dim v As Json
    v = j[key]

    If v.IsBoolean() Then
        SafeGetBoolean = j.GetBoolean(key)

    ElseIf v.IsInteger() Then
        SafeGetBoolean = (j.GetInteger(key) <> 0)

    ElseIf v.IsString() Then
        Dim tmp As String
        tmp = j.GetString(key)

        If tmp = "true" OR tmp = "True" OR tmp = "1" Then
            SafeGetBoolean = True
        ElseIf tmp = "false" OR tmp = "False" OR tmp = "0" Then
            SafeGetBoolean = False
        Else
            SafeGetBoolean = def
        End If

    Else
        SafeGetBoolean = def
    End If

End Function

End Function

View attachment 222037

THANK YOU SO MUCH!!!
Very important information here.
 
DataPool DataReader is kind of limited. I have to read the whole file and arrange the scene to follow to sequence of the data in the json file,I prefer to be able to read randomly from the within the json file.
 
Back
Top