Results 1 to 17 of 17

Thread: JSON Parser

  1. #1

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    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

  2. #2
    New Member
    Join Date
    May 2011
    Posts
    1

    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>"

  3. #3

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    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.

  4. #4
    Wait... what? weirddemon's Avatar
    Join Date
    Jan 2009
    Location
    USA
    Posts
    3,828

    Re: JSON Parser

    Quote Originally Posted by minitech View Post
    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:
    1. MessageBox.Show(CStr(jsonParser.GetProperty("modhash").Value))

    Any ideas?
    CodeBank contributions: Process Manager, Temp File Cleaner

    Quote Originally Posted by SJWhiteley
    "game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....

  5. #5

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    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:
    1. MessageBox.Show(DirectCast(jsonParser.GetProperty("data").Value, JSONObject).GetProperty("modhash").Value.ToString())

  6. #6
    Wait... what? weirddemon's Avatar
    Join Date
    Jan 2009
    Location
    USA
    Posts
    3,828

    Re: JSON Parser

    Quote Originally Posted by minitech View Post
    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:
    1. 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

    Quote Originally Posted by SJWhiteley
    "game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....

  7. #7

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    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...

  8. #8
    New Member
    Join Date
    Mar 2012
    Posts
    1

    Re: JSON Parser

    Minitech, your JSON parser is really nice.
    How about using DynamicObject to make results more usable?

  9. #9

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    Re: JSON Parser

    Quote Originally Posted by Andrea Antonangeli View Post
    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

  10. #10
    New Member
    Join Date
    Sep 2012
    Posts
    1

    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

  11. #11
    New Member
    Join Date
    Sep 2012
    Posts
    2

    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:
    1. {"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:
    1. DirectCast(jsonParser.GetProperty("payload").Value, JSONObject).GetProperty("uri").Value.ToString()
    Regards,
    IAL32

  12. #12
    New Member
    Join Date
    Sep 2012
    Posts
    2

    Re: JSON Parser

    Err...up?

  13. #13
    New Member
    Join Date
    Nov 2012
    Posts
    2

    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 :-(

  14. #14

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    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.

  15. #15
    New Member
    Join Date
    Nov 2012
    Posts
    2

    Re: JSON Parser

    which one would you recommend minitech ? (for VB.Net)

  16. #16
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    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.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  17. #17
    New Member
    Join Date
    Jul 2013
    Posts
    1

    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
  •  



Click Here to Expand Forum to Full Width