user5026161
user5026161

Reputation:

Get json value in VB.NET

How can I get the name of a key in a json file? I have a json that I'm parsing in VB.NET and one of the 'fields' have a dynamic name (it changes). What could I do to get the key name?

For example:

...

"one":{  
                        "two":{  
                           "example":[  
                              {  
                                 "aaa":"test",
                                 "bbb":"test",
                                 "ccc":"test"
                              },

...

I'm getting correctly all the values (test, test, test...) and the keys 'one', 'two', have always the same name. But the key 'example' changes the name according the json file information. How could I identify the key text?

Upvotes: 0

Views: 3107

Answers (3)

fcm
fcm

Reputation: 1331

This piece will allow to get data from an unknown JSON structure, without having to define a class.

Sample

Dim serializer As System.Web.Script.Serialization.JavaScriptSerializer
serializer = New JavaScriptSerializer()
' {"elements":[{"handle~":{"emailAddress":"[email protected]"},"handle":"urn:li:emailAddress:348955221"}]}
dim json as string
Dim obj As System.Collections.Generic.IDictionary(Of String, Object)
obj = serializer.Deserialize(Of System.Collections.Generic.IDictionary(Of String, Object))(json)
dim email as string=string.empty
email = If(GetJsonValue(obj, {"elements", "handle~", "emailAddress"}.ToList()), email)

The Function, very self descriptive:

''' <summary>decode json data </summary>
Public Function GetJsonValue(ByVal obj As Object,
                          ByVal key As List(Of String)) As String
   GetJsonValue = Nothing
    '   If the object is an array, assume any element can contain the key
    If obj.GetType Is GetType(Object()) Then 
        For Each newObj As Object In CType(obj, Object())
            Dim tmp As String = GetJsonValue(newObj, key)
            If Not String.IsNullOrEmpty(tmp) Then Return tmp
        Next
    Else
        Dim objEle As System.Collections.Generic.IDictionary(Of String, Object)
        Dim keyName As String
        Dim objKey As String
        '
        keyName = key(0)
        objEle = CType(obj, System.Collections.Generic.IDictionary(Of String, Object))
        objKey = objEle.Keys.ToArray()(0)

        If objEle.ContainsKey(keyName) Then
            Dim temp As Object = objEle.Item(keyName)
            If key.Count > 1 Then
                ' if the element is array, we need to get the array element and move to the next
                key.RemoveAt(0)
                Return GetJsonValue(temp, key)
            Else
                Return temp.ToString()
            End If
        End If
    End If

End Function

Upvotes: 1

GMan80013
GMan80013

Reputation: 536

I see this is solved but would like to suggest another solution for future readers. The JavaScriptSerializer can return a nested dictionary collection (Of String, Object). I find it easier to explore the result in debug while coding. The code below shows an example of how to navigate the collections.

  Dim deserializer As New System.Web.Script.Serialization.JavaScriptSerializer

  Dim text As String = "{""two"":{""example"":[{""aaa"":""test"",""bbb"":""test"",""ccc"":""test""}]}}"
  Dim dict As Dictionary(Of String, Object) = deserializer.DeserializeObject(text)

  Dim keys As Dictionary(Of String, Object).KeyCollection
  keys = dict("two")("example")(0).Keys

  Dim aaaName As String = keys(0)
  Dim aaaValue As String = dict("two")("example")(0)(aaaName)

Upvotes: 0

David
David

Reputation: 6111

I wrote a piece of code that converts JSON into a XDocument here: https://github.com/dday9/.NET-JSON-Transformer

If you were to use that code, then you could get the node that represents your "two" object and then get the first child node in to. By doing this, you're essentially getting the array by an Index instead of by a name.

Here is a quick example of what I mean:

Dim literal As String = "{""two"":{""example"":[{""aaa"":""test"",""bbb"":""test"",""ccc"":""test""}]}}"
Dim xJSON As XDocument = JSON.Parse(literal)
Dim object_two As XElement = xJSON.Descendants("two").FirstOrDefault()
If object_two IsNot Nothing Then
    Dim first_descendent As XElement = object_two.Descendants().Skip(1).FirstOrDefault()

    If first_descendent IsNot Nothing Then
        Console.WriteLine(first_descendent)
    End If
End If

Fiddle: Live Demo

Upvotes: 1

Related Questions