-
Mar 22nd, 2011, 08:07 PM
#1
Thread Starter
Stack Overflow moderator
JSON Parser
Here's a JSON parser I created. To evaluate a JSON object, use New JSONObject(theJSONString). To retrieve a property, use JSONObject.GetProperty(name).
Code:
Imports System.Text.RegularExpressions
Public Class JSONObject
#Region "Shared Variables"
Private Shared ReadOnly reProp As New Regex("(?<=(^|\,)\s*)([^\:]+)\s*\:\s*([^\,]+)", RegexOptions.Compiled)
Private Shared ReadOnly reReplaced As New Regex("^\$\[\d+\]$", RegexOptions.Compiled)
#End Region
#Region "Shared Functions"
Private Shared Function TokenizeJSON(ByVal json As String, ByVal l As List(Of String)) As String
Dim r As String = String.Empty,
nestable As String = "()[]{}",
stringable As String = """'",
nested As New Stack(Of Char),
stringing As Char? = Nothing,
start As Integer = -1
l.Clear()
For i As Integer = 0 To json.Length - 1
Dim c As Char = json(i)
If stringing IsNot Nothing Then
If stringing = c Then
stringing = Nothing
If nested.Count = 0 Then
r &= "$[" & l.Count.ToString() & "]"
l.Add(json.Substring(start, i - start + 1))
End If
End If
ElseIf stringable.IndexOf(c) > -1 Then
stringing = c
If nested.Count = 0 Then start = i
ElseIf nestable.IndexOf(c) Mod 2 = 0 Then
If nested.Count = 0 Then start = i
nested.Push(c)
ElseIf nested.Count > 0 Then
If nestable.IndexOf(nested.Peek()) + 1 = nestable.IndexOf(c) Then
nested.Pop()
If nested.Count = 0 Then
r &= "$[" & l.Count.ToString() & "]"
l.Add(json.Substring(start, i - start + 1))
End If
End If
Else
r &= If(c = "\" OrElse c = "$", "\" & c, c)
End If
Next
Return r
End Function
Private Shared Function ParseJSONObject(ByVal json As String) As Dictionary(Of String, String)
Dim r As New Dictionary(Of String, String),
l As New List(Of String)
'Trim any leading or trailing object delimiters found in JSON objects.
json = json.TrimStart("{"c, "("c, " "c).TrimEnd("}"c, ")"c, " "c)
'Tokenize the JSON object.
json = TokenizeJSON(json, l)
'Parse the JSON object.
For Each m As Match In reProp.Matches(json)
Dim name As String = m.Groups(2).Value.TrimStart()
Dim value As String = m.Groups(3).Value
If reReplaced.IsMatch(name) Then name = l(Integer.Parse(name.Substring(2, name.Length - 3)))
If reReplaced.IsMatch(value) Then value = l(Integer.Parse(value.Substring(2, value.Length - 3)))
name = name.Trim("'"c, """"c)
r.Add(name, value)
Next
'Return the result.
Return r
End Function
Private Shared Function ParseJSONArray(ByVal json As String) As String()
Dim l As New List(Of String),
r As New List(Of String)
'Trim any leading or trailing array delimiters found in JSON objects, but only one on each side.
json = json.Trim()
json = json.Substring(1, json.Length - 2)
'Tokenize the JSON array.
json = TokenizeJSON(json, l)
'Parse and return the JSON array.
For Each y As String In (From x As String In json.Split(","c) Select x.Trim())
If reReplaced.IsMatch(y) Then
r.Add(l(Integer.Parse(y.Substring(2, y.Length - 3))))
Else
r.Add(y)
End If
Next
Return r.ToArray()
End Function
#End Region
#Region "Variables"
Private ReadOnly _properties As Dictionary(Of String, String)
#End Region
#Region "Constructor"
Public Sub New(ByVal json As String)
_properties = JSONObject.ParseJSONObject(json)
End Sub
#End Region
#Region "Methods"
Public Function GetProperty(ByVal name As String) As JSONValue
If _properties.ContainsKey(name) Then Return Evaluate(_properties(name))
Return New JSONValue(JSONType.undefined, Nothing)
End Function
Private Function Evaluate(ByVal json As String) As JSONValue
Dim intValue As Integer,
floatValue As Double
json = json.TrimStart("("c).TrimEnd(")"c)
If json <> String.Empty Then
If json(0) = "{"c Then
Return New JSONValue(JSONType.object, New JSONObject(json))
ElseIf json(0) = "["c Then
Return New JSONValue(JSONType.array, (From x As String In JSONObject.ParseJSONArray(json) Select Evaluate(x)).ToArray())
ElseIf json(0) = "'"c OrElse json(0) = """"c Then
Return New JSONValue(JSONType.string, json.Substring(1, json.Length - 2))
ElseIf Integer.TryParse(json, intValue) Then
Return New JSONValue(JSONType.int, intValue)
ElseIf Double.TryParse(json, floatValue) Then
Return New JSONValue(JSONType.double, floatValue)
ElseIf json = "true" Then
Return New JSONValue(JSONType.bool, True)
ElseIf json = "false" Then
Return New JSONValue(JSONType.bool, False)
ElseIf json = "null" Then
Return New JSONValue(JSONType.null, Nothing)
End If
End If
Return New JSONValue(JSONType.undefined, Nothing)
End Function
#End Region
End Class
Public Class JSONValue
Private _type As JSONType,
_value As Object
Public Sub New(ByVal type As JSONType, ByVal value As Object)
_type = type
_value = value
End Sub
Public ReadOnly Property Type() As JSONType
Get
Return _type
End Get
End Property
Public ReadOnly Property Value() As Object
Get
Return _value
End Get
End Property
End Class
Public Enum JSONType
bool
int
[double]
[string]
[object]
array
null
undefined
End Enum
-
May 31st, 2011, 03:06 PM
#2
New Member
Re: JSON Parser
The parsing mechanism works great, but, ran into a small issue when HTML is embedded within the JSON response. The TokenizeJSON function is "breaking" on the doubled quote as it "thinks" the next double quote is the ending or the beginning of the next property/value. Any thoughts you may would be very helpful.
Here is the JSON response with the HTML property...
"html":"<div class=\"info message-1507293770\">\n <div class=\"sent\"><span>Sent:<\/span> Mon, 30 May<\/div>\n <div class=\"from\"><span>From:<\/span> friday_night_8<\/div>\n <div class=\"from\"><span>Subject:<\/span>\n heh?\n <\/div>\n<\/div>\n<div class=\"message\">are you a vegetarian?<\/div>"
-
May 31st, 2011, 07:36 PM
#3
Thread Starter
Stack Overflow moderator
Re: JSON Parser
Hm... and yet the "stringable" and "stringing" variables should be there to counteract that! I haven't tested this extensively, but I will try to in the near future and I will attempt to fix the problem you describe.
-
Jul 23rd, 2011, 03:24 PM
#4
Re: JSON Parser
Originally Posted by minitech
Hm... and yet the "stringable" and "stringing" variables should be there to counteract that! I haven't tested this extensively, but I will try to in the near future and I will attempt to fix the problem you describe.
Minitech,
I'm attempting to use your parser to grab some data from Reddit. I'm trying to grab the "about" data for a user and whenever I specify "kind", it works, but anything else also shows an empty string.
JSON:
{"kind": "t2", "data": {"has_mail": false, "name": "weirddemon", "created": 1310935327.0, "modhash": "mavzqjcspta940d5218c7a971ec6865dcb886742adba6bf098", "created_utc": 1310935327.0, "link_karma": 1, "comment_karma": 0, "is_gold": false, "is_mod": false, "id": "5j1qm", "has_mod_mail": false}}
Code:
VB.NET Code:
MessageBox.Show(CStr(jsonParser.GetProperty("modhash").Value))
Any ideas?
CodeBank contributions: Process Manager, Temp File Cleaner
Originally Posted by SJWhiteley
"game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....
-
Jul 23rd, 2011, 03:51 PM
#5
Thread Starter
Stack Overflow moderator
Re: JSON Parser
The "modhash" property is a property of the "data" object, not the base JSON object. Your code should look something like this:
VB.NET Code:
MessageBox.Show(DirectCast(jsonParser.GetProperty("data").Value, JSONObject).GetProperty("modhash").Value.ToString())
-
Jul 23rd, 2011, 04:10 PM
#6
Re: JSON Parser
Originally Posted by minitech
The "modhash" property is a property of the "data" object, not the base JSON object. Your code should look something like this:
VB.NET Code:
MessageBox.Show(DirectCast(jsonParser.GetProperty("data").Value, JSONObject).GetProperty("modhash").Value.ToString())
Oh, I gotcha. I'll have to play around with that then. That specific line throws an Object reference not set to an instance of an object. exception, probably when casting the JSONObject.
CodeBank contributions: Process Manager, Temp File Cleaner
Originally Posted by SJWhiteley
"game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....
-
Jul 23rd, 2011, 04:13 PM
#7
Thread Starter
Stack Overflow moderator
Re: JSON Parser
Hm. Sorry, I'm on a Mac away from home for the next few weeks, I can't debug... I'll try a complete rewrite sometime.
In the debugger, you can tell which expression resolves to Nothing, once you find that can you tell me so I can fix it?
Sorry about that...
-
Mar 18th, 2012, 12:56 PM
#8
New Member
Re: JSON Parser
Minitech, your JSON parser is really nice.
How about using DynamicObject to make results more usable?
-
Mar 18th, 2012, 01:00 PM
#9
Thread Starter
Stack Overflow moderator
Re: JSON Parser
Originally Posted by Andrea Antonangeli
Minitech, your JSON parser is really nice.
How about using DynamicObject to make results more usable?
Good idea - I haven't touched this in a while. I'll do that now. Thanks
-
Sep 29th, 2012, 12:00 PM
#10
New Member
Re: JSON Parser
I know this thread is real old but can someone tell me why this doesn't work.
Dim jsonParser As New JSONObject(Label14.Text)
MessageBox.Show(DirectCast(jsonParser.GetProperty("data").Value, JSONObject).GetProperty("modhash").Value.ToString())
{"kind": "t2", "data": {"has_mail": false, "name": "weirddemon", "created": 1310935327.0, "modhash": "mavzqjcspta940d5218c7a971ec6865dcb886742adba6bf098", "created_utc": 1310935327.0, "link_karma": 1, "comment_karma": 0, "is_gold": false, "is_mod": false, "id": "5j1qm", "has_mod_mail": false}}
is label14 text its a example someone posted in here but when I try it, it doesn't work
-
Sep 30th, 2012, 06:20 AM
#11
New Member
Re: JSON Parser
Hi, i'm using this JSON string, but when i try to get the uri property, it gives me a NullReferenceException:
vbnet Code:
{"success":true,"payload":{"uid":"Gals","uri":"http://i.imm.io/Gals.png","link":"http://imm.io/Gals","name":"Capitolo1_1.PNG","format":"PNG","ext":"png","width":1279,"height":745,"size":"193 KB"}}
I'm using the following method:
vbnet Code:
DirectCast(jsonParser.GetProperty("payload").Value, JSONObject).GetProperty("uri").Value.ToString()
Regards,
IAL32
-
Nov 13th, 2012, 04:58 PM
#12
New Member
-
Nov 14th, 2012, 04:00 AM
#13
New Member
Re: JSON Parser
Hmm, I'm having the same issue if I want to get the geo coordinates of a twitter json string...: null reference exception :-(
-
Dec 27th, 2012, 10:19 PM
#14
Thread Starter
Stack Overflow moderator
Re: JSON Parser
Ah, I missed these. Sorry! I could still work on this if anyone wants it (even just for some kind of reference), but there are some really good JSON libraries out there that already exist. Use those.
-
Jan 2nd, 2013, 03:19 AM
#15
New Member
Re: JSON Parser
which one would you recommend minitech ? (for VB.Net)
-
Jan 2nd, 2013, 08:10 AM
#16
Re: JSON Parser
Since I make JSON with this
Code:
Dim sJson As String = ""
Dim listJson As Dictionary(Of String, String) = New Dictionary(Of String, String)
.
.
listJson.Add("docsize", allText.Length.ToString)
.
.
sJson = New System.Web.Script.Serialization.JavaScriptSerializer().Serialize(listJson)
I assume you can find a deserialize method as well.
-
Jul 21st, 2013, 10:06 AM
#17
New Member
Re: JSON Parser
I like a lot the parser proposed below but I cannot parse this link
http://earthquake.usgs.gov/earthquak...00ij2v.geojson
in order to get
products...
it reads a lot of properties but skips this that this quite important.
Thanks
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|