Proger_Cbsk Proger_Cbsk - 2 months ago 8
Vb.net Question

How to get key and key's children value with JSON.net

I'm trying to convert a json into a flat file for a database.
In order to do that, i have to pick up some value in the root node, then a key in a specific children, then each of the key's children value.

It turns out to be a nightmare with the

for each
and cast issue between
JObject
,
JToken
and
JProperty


The source JSON

{
"id": "030010014B",
"type": "street",
"housenumbers": {
"13": {
"lat": 46.085617,
"lon": 3.460492
},
"1bis": {
"lat": 46.08686,
"lon": 3.459992
},
"5": {
"lat": 46.086469,
"lon": 3.460912
}
}
}


The expected result

// <id value>;<key of housenumber #>;<lon value>;<lat value>
030010014B;13;3.460492;46.085617
030010014B;1bis;3.459992;46.08686
030010014B;5;3.460912;46.086469


Current code that fails miserabily

Dim tmpJson As JObject = JObject.Parse(<json sample as string>)
Dim house As JToken
Dim house_p As JToken
If tmpJson.Property("housenumbers") IsNot Nothing Then
For Each houses As JObject In tmpJson.Property("housenumbers").Children 'only one
For Each house In houses.Descendants
fs.Append(tmpJson.Property("id").Value.ToString & ";")
Dim hh As JProperty = house 'failing here
fs.Append(hh.Name & ";") 'no way to get a key without jproperty
For Each house_p In house.Children()
fs.AppendLine(house_p.Value(Of String)("lon") & ";" & house_p.Value(Of String)("lat"))
Next
Next
Next
End If
...


My failing example is inspired from the C# answers around SO but the "value to keys to values" seems rather rare.

Answer

You can get them as a collection of objects and iterate that:

Public Class Location
    <JsonProperty("lat")>
    Public Property Latitude As Single
    <JsonProperty("lon")>
    Public Property Longitude As Single
End Class

Then deserialize the inner part into sa Dictionary:

Dim jstr = from whereever
Dim jobj = JObject.Parse(jstr)

Dim id As String = jobj("id").ToString

Dim numbers = JsonConvert.DeserializeObject(Of Dictionary(Of String, Location))(jobj("housenumbers").ToString())

For Each kvp In numbers
    Console.WriteLine("key:{0}, lat: {1}, long: {2}",
                      kvp.Key, kvp.Value.Latitude,
                      kvp.Value.Longitude)
Next

key:13, lat: 46.08562, long: 3.460492
key:1bis, lat: 46.08686, long: 3.459992
key:5, lat: 46.08647, long: 3.460912

The 030010014B would be in your Id variable

Comments