Android Code Snippet [B4X] IsValidJSON (Conclusion)

I am sharing a routine that I use to validate JSON.
Test comments are welcome.

thanks to @aeric for his contribution
B4X: Copy
Public Sub IsValidJSON(sJson As String) As Boolean
    Try
        sJson = sJson.Trim
        If sJson.StartsWith("[") And sJson.EndsWith("]") Then Return sJson.As(JSON).ToList.IsInitialized
        If sJson.StartsWith("{") And sJson.EndsWith("}") Then Return sJson.As(JSON).ToMap.IsInitialized
        Return False
    Catch
        Log(LastException.Message) 'display json error
        Return False
    End Try
End Sub
B4X: Copy
    Dim sJson As String = $"[2,"C"]"$
    Log(IsValidJSON(sJson))
    Log("-------------------------")
    Dim sJson As String = $"{car:"Toyota",model:"Prado",prices: [{year:2020,price:20000},{year:2019,price:17000},{year:2020,price:}]}"$ 'Error in price
    Log(IsValidJSON(sJson))
    Log("-------------------------")
    Dim sJson As String = $"{car:"Toyota",model:"Prado",prices: [{year:2020,price:20000},{year:2019,price:17000},{year:2015,price:12000}]}"$
    Log(IsValidJSON(sJson))
    Log("-------------------------")
    Dim sJson As String = $"{"menu":{"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"Close()"}]}}}"$
    Log(IsValidJSON(sJson))
    Log("-------------------------")
    Dim sJson As String = $"{"id":"chatcmpl-6t2JQdgU1ypn0ayhONAkE6bAEoGkz","object":"chat.completion","created":1678574948,"model":"gpt-3.5-turbo-0301","usage":{"prompt_tokens":25,"completion_tokens":110,"total_tokens":135},"choices":[{"message":{"role":"assistant","content":"Ahoy matey, ye be askin' a great question. The worst investment be ones that promise quick riches without flappin' yer sails too much, like the \"get rich quick\" schemes, ponzi schemes Or pyramid schemes. These scams be all about misuse of trust And deceivin' the inexperienced. They be luring investors with high promised returns, but in the end, they just take yer doubloons and disappear into the horizon. Stay away from such crooks and keep yer treasure safe, me hearty!"},"finish_reason":"stop","index":0}]}}"$
    Log(IsValidJSON(sJson))
1690506116357.png


Test 2
B4X: Copy
Public Sub IsValidJSON(sJson As String) As Boolean
    Dim obj As Object
    Try
        sJson = sJson.Trim
        Select True
            Case sJson.StartsWith("[") And sJson.EndsWith("]")
                obj = sJson.As(JSON).ToList
            Case sJson.StartsWith("{") And sJson.EndsWith("}")
                obj = sJson.As(JSON).ToMap
            Case Else
                Return False
        End Select
        obj = obj.As(JSON).ToString
        Log(obj.As(String)) 'display json text
        Return True
    Catch
        Log(LastException.Message) 'display json error
        Return False
    End Try
End Sub
Test:
B4X: Copy
    Dim sJson As String = $"[{"Monday": 2, "Thursday": 5, "Friday": 6, "Sunday": 1, "Wednesday": 4, "Tuesday": 3, "Saturday": 7 }"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"[{"Monday": 2, "Thursday": 5, "Friday": 6, "Sunday": 1, "Wednesday": 4, "Tuesday": 3, "Saturday": 7 }]"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"{"Monday": 2, "Thursday": 5, "Friday": 6, "Sunday": 1, "Wednesday": 4, "Tuesday": 3, "Saturday": 7 }"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"{}"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"[]"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"[dsdsdsd:]"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"{"dsdsdsd":}"$
    Log(IsValidJSON(sJson))
    Dim sJson As String = $" "$
    Log(IsValidJSON(sJson))
    Dim sJson As String = Null
    Log(IsValidJSON(sJson))
    Dim sJson As String = $"null"$
    Log(IsValidJSON(sJson))

1690425664437.png
 
Last edited:
B4X: Copy
Private Sub IsValidJson(jsonString As String) As Boolean
    Dim stack As List ' Stack to keep track of opened brackets/braces
    stack.Initialize
    Dim inString As Boolean ' Flag to indicate if currently inside a string
    Dim escapeNextChar As Boolean ' Flag to indicate if the next character is escaped
    Dim i As Int

    For i = 0 To jsonString.Length - 1
        Dim c As Char = jsonString.CharAt(i)

        If escapeNextChar Then ' If the previous character was an escape character '\'
            escapeNextChar = False ' Reset the flag as the next character is escaped.
            Continue ' Move to the next character without further processing.
        End If

        If c = "\" Then ' Check for escape character '\'
            escapeNextChar = True ' Set the flag to indicate that the next character is escaped.
        Else If c = """" Then ' Check for double quote to indicate start/end of a string.
            inString = Not(inString) ' Toggle the flag for inside/outside of a string.
        End If

        If Not(inString) Then ' Process characters only outside of a string.
            If c = "{" Or c = "[" Then ' Opening brace or bracket found.
                stack.Add(c) ' Add it to the stack.
            Else If c = "}" Or c = "]" Then ' Closing brace or bracket found.
                If stack.Size = 0 Or stack.Get(stack.Size - 1) <> GetMatchingOpeningChar(c) Then
                    Return False ' Unmatched closing brace/bracket, invalid JSON.
                Else
                    stack.RemoveAt(stack.Size - 1) ' Remove the matched opening brace/bracket.
                End If
            End If
        End If
    Next

    Return stack.Size = 0 ' If the stack is empty, it means all opening braces/brackets are matched.
End Sub

Private Sub GetMatchingOpeningChar(c As Char) As Char
    Select Case c
        Case "}": Return "{"
        Case "]": Return "["
        Case Else: Return Chr(0) ' Return a null character for unmatched closing character.
    End Select
End Sub

I use this routine because sometimes the JSON library will cause an exception on invalid json.
 
B4X: Copy
Private Sub IsValidJson(jsonString As String) As Boolean
    Dim stack As List ' Stack to keep track of opened brackets/braces
    stack.Initialize
    Dim inString As Boolean ' Flag to indicate if currently inside a string
    Dim escapeNextChar As Boolean ' Flag to indicate if the next character is escaped
    Dim i As Int

    For i = 0 To jsonString.Length - 1
        Dim c As Char = jsonString.CharAt(i)

        If escapeNextChar Then ' If the previous character was an escape character '\'
            escapeNextChar = False ' Reset the flag as the next character is escaped.
            Continue ' Move to the next character without further processing.
        End If

        If c = "\" Then ' Check for escape character '\'
            escapeNextChar = True ' Set the flag to indicate that the next character is escaped.
        Else If c = """" Then ' Check for double quote to indicate start/end of a string.
            inString = Not(inString) ' Toggle the flag for inside/outside of a string.
        End If

        If Not(inString) Then ' Process characters only outside of a string.
            If c = "{" Or c = "[" Then ' Opening brace or bracket found.
                stack.Add(c) ' Add it to the stack.
            Else If c = "}" Or c = "]" Then ' Closing brace or bracket found.
                If stack.Size = 0 Or stack.Get(stack.Size - 1) <> GetMatchingOpeningChar(c) Then
                    Return False ' Unmatched closing brace/bracket, invalid JSON.
                Else
                    stack.RemoveAt(stack.Size - 1) ' Remove the matched opening brace/bracket.
                End If
            End If
        End If
    Next

    Return stack.Size = 0 ' If the stack is empty, it means all opening braces/brackets are matched.
End Sub

Private Sub GetMatchingOpeningChar(c As Char) As Char
    Select Case c
        Case "}": Return "{"
        Case "]": Return "["
        Case Else: Return Chr(0) ' Return a null character for unmatched closing character.
    End Select
End Sub

I use this routine because sometimes the JSON library will cause an exception on invalid json.
Can you post a Json example to check?
 
I recall this thread
 
I recall this thread
yes,
This routine is only for validating the json format.
Same logic, I use it to identify if the json text is a Map or a List
 
Here is my version which use IsInitialized.

B4X: Copy
Sub IsValidJSON (str As String) As Boolean
    str = str.Trim
    Try
        Select True
            Case str.StartsWith("[") And str.EndsWith("]")
                Return str.As(JSON).ToList.IsInitialized
            Case str.StartsWith("{") And str.EndsWith("}")
                Return str.As(JSON).ToMap.IsInitialized
            Case Else
                Return False
        End Select
    Catch
        Log(LastException.Message)
    End Try
    Return False
End Sub
 
simply ordering the code to respect the try catch

B4X: Copy
Sub IsValidJSON(sJson As String) As Boolean
    Try
        sJson = sJson.Trim
        Select True
            Case sJson.StartsWith("[") And sJson.EndsWith("]") : Return sJson.As(JSON).ToList.IsInitialized
            Case sJson.StartsWith("{") And sJson.EndsWith("}") : Return sJson.As(JSON).ToMap.IsInitialized
            Case Else : Return False
        End Select
    Catch
'        Log(LastException.Message)
        Return False
    End Try
End Sub
 
Last edited:
Invalid json, or valid json?

If invalid json, then perhaps use Try ... Catch to reduce program complexity and size and probably run time, not to mention programming time spent effectively rewriting a json parser. Unless you're going for space shuttle reliability by writing multiple versions of the program and putting their output to a vote. ?
please see the post

Tiene otra ventaja, que indica dónde está el error.
1690506098000.png
 
I haven't tested if let say the key of a map is non-English. Would it be valid too?
How about some characters that need to be escaped?
 
Back
Top