Reputation: 387
I have nested JSON strings that i would like to parse out the appropriate values from much like below. As i am learning by doing I am struggling a little bit, I have the first part working in that I can parse out single JSON strings, and return the appropriate value using code example 1 below, however i am stuck with a JSON string that is problematic in that it is nested, so the same approach won't work
{
"jsonrpc":"2.0",
"method":"Player.OnPause",
"params":{
"data": { "item": { "id":29, "type":"episode" },
"player": { "playerid":1, "speed":0 }
},
"sender":"xbmc"
}
}
And the code...
Dim JSON As String
Dim values As Newtonsoft.Json.Linq.JObject
JSON = JSON STRING WOULD GO HERE, COMES from TCP IP STREAM
values = JObject.Parse(JSON)
Console.WriteLine(values.GetValue("method"))
Using that example i can extract the method key (e.g. Player.OnPause) from the first level JSON string, but how can i extract data from the second, and third level strings, For example in the above string, being able to get to Data level JSON values, and Item level JSON values. Is this possible in a similar way to the above?
Appreciate any tips you could provide, I am a learn by examples person, but just struggling to apply something to read multiple nested JSON strings, or multiple levels. No doubt it will be an easy thing that i am missing, but id appreciate any help someone could provide.
Thanks
Upvotes: 4
Views: 19864
Reputation: 41
After searching here and else where for an polymorhic example of parsing javascrip object notation into a .net dictionary I gave up and wrote my own. Hope someone finds this useful ;)
Public Class jsonDictionary
Inherits Dictionary(Of String, Object)
#Region "Public Properties"
Private _parent As jsonDictionary
Public ReadOnly Property Parent() As jsonDictionary
Get
Return _parent
End Get
End Property
#End Region
#Region "Initialisation and Finalisation"
Public Sub New(ByVal Parent As jsonDictionary, ByVal strJson As String)
_parent = Parent
For Each Element As String In SplitJSON(CharTrim(strJson))
Dim elName As String = CharTrim(Element.Split(":")(0).Trim)
Select Case Element.Split(":")(1).Trim.Substring(0, 1)
Case "{"
Me.Add(elName, New jsonDictionary(Me, Element.Substring(InStr(Element, ":"))))
Case "["
Dim ElArray As New List(Of jsonDictionary)
For Each ArrayElement As String In SplitJSON(CharTrim(Element.Substring(InStr(Element, ":"))))
ElArray.Add(New jsonDictionary(Me, ArrayElement))
Next
Me.Add(elName, ElArray)
Case Else
Me.Add(elName, Element.Split(":")(1).Trim)
End Select
Next
End Sub
#End Region
#Region "Private Methods"
Public Shared Function CharTrim(ByVal Str As String) As String
Return Str.Trim.Substring(1, Str.Length - 2)
End Function
Private Function SplitJSON(ByVal str As String) As String()
Dim ret() As String = Nothing
Dim sqCount As Integer = 0
Dim clCount As Integer = 0
Dim buildStr As New System.Text.StringBuilder
For i As Integer = 0 To str.Length - 1
Select Case str.Substring(i, 1)
Case ","
If sqCount = 0 And clCount = 0 Then
Try
ReDim Preserve ret(UBound(ret) + 1)
Catch ex As Exception
ReDim ret(0)
Finally
ret(UBound(ret)) = buildStr.ToString
buildStr = New System.Text.StringBuilder
End Try
Else
buildStr.Append(str.Substring(i, 1))
End If
Case Else
buildStr.Append(str.Substring(i, 1))
Select Case str.Substring(i, 1)
Case "["
sqCount += 1
Case "]"
sqCount -= 1
Case "{"
clCount += 1
Case "}"
clCount -= 1
End Select
End Select
Next
If buildStr.ToString.Length > 0 Then
Try
ReDim Preserve ret(UBound(ret) + 1)
Catch ex As Exception
ReDim ret(0)
Finally
ret(UBound(ret)) = buildStr.ToString
End Try
End If
Return ret
End Function
#End Region
End Class
Upvotes: 4
Reputation: 1785
Dim jsonstring = IO.File.ReadAllText("json.txt")
Dim jo = Json.Linq.JObject.Parse(jsonstring)
Dim playerid = jo("params")("data")("player")("playerid")
Do you mean something like this? "json.txt" simply contains your JSON string.
Upvotes: 7