Android Question JSON parser (map or list)

freedom2000

Well-Known Member
Licensed User
Longtime User
HI,

I am trying to parse "beerXML" recipes. I have already translated them into JSON successfully, and I would like to parse the JSON now.

Here is a first example with two "MASH_STEP" nested in an Array
B4X:
 {"MASH": {
        "NAME": "Mash Steps",
        "VERSION": "1",
        "GRAIN_TEMP": "20",
        "MASH_STEPS": {
          "MASH_STEP": [
            {
              "NAME": "Rest",
              "VERSION": "1",
              "TYPE": "Temperature",
              "STEP_TIME": "60",
              "INFUSE_AMOUNT": "18.9270589",
              "STEP_TEMP": "67.222222222222"
            },
            {
              "NAME": "Mash-out Rest",
              "VERSION": "1",
              "TYPE": "Temperature",
              "STEP_TIME": "10",
              "STEP_TEMP": "75.555555555556"
            }
          ]
        }
      }}

The code to read the "MASH_STEP" uses a list to access the Array
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim MASH As Map = root.Get("MASH")
Dim GRAIN_TEMP As String = MASH.Get("GRAIN_TEMP")
Dim VERSION As String = MASH.Get("VERSION")
Dim NAME As String = MASH.Get("NAME")
Dim MASH_STEPS As Map = MASH.Get("MASH_STEPS")
Dim MASH_STEP As List = MASH_STEPS.Get("MASH_STEP")
For Each colMASH_STEP As Map In MASH_STEP
    Dim STEP_TEMP As String = colMASH_STEP.Get("STEP_TEMP")
    Dim STEP_TIME As String = colMASH_STEP.Get("STEP_TIME")
    Dim INFUSE_AMOUNT As String = colMASH_STEP.Get("INFUSE_AMOUNT")
    Dim VERSION As String = colMASH_STEP.Get("VERSION")
    Dim TYPE As String = colMASH_STEP.Get("TYPE")
    Dim NAME As String = colMASH_STEP.Get("NAME")
Next



Here is a second example with only one "MASH_STEP" (it's another recipe found on the same web site)

B4X:
{"MASH": {
        "NAME": "Mash Steps",
        "VERSION": "1",
        "GRAIN_TEMP": "20",
        "MASH_STEPS": {
          "MASH_STEP": {
            "VERSION": "1",
            "TYPE": "Infusion",
            "STEP_TIME": "60",
            "STEP_TEMP": "66.666666666667"
          }
        }
      }}

The MASH_STEP is read from a map.
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim MASH As Map = root.Get("MASH")
Dim GRAIN_TEMP As String = MASH.Get("GRAIN_TEMP")
Dim VERSION As String = MASH.Get("VERSION")
Dim NAME As String = MASH.Get("NAME")
Dim MASH_STEPS As Map = MASH.Get("MASH_STEPS")
Dim MASH_STEP As Map = MASH_STEPS.Get("MASH_STEP")
Dim STEP_TEMP As String = MASH_STEP.Get("STEP_TEMP")
Dim STEP_TIME As String = MASH_STEP.Get("STEP_TIME")
Dim VERSION As String = MASH_STEP.Get("VERSION")
Dim TYPE As String = MASH_STEP.Get("TYPE")

If I try to read the second JSON with the code with an Array, it crashes on the line :
B4X:
For Each colMASH_STEP As Map In MASH_STEP

An array is read via a list, a key/value pair via a map...
I would like the same code to be able to auto detect the two situations. Any idea how to do it without throwing an exception ?

Thanks
 
Last edited:

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi,

I found this trick : check the [ character... Don't know if it's clean but it works !
B4X:
        Dim MASH_STEPS As Map = MASH.Get("MASH_STEPS")
            Dim tt As String = MASH_STEPS.Get("MASH_STEP")
            Dim STEP_TEMP As String
             Dim STEP_TIME As String
             Dim INFUSE_AMOUNT As String
             Dim VERSION As String
             Dim xType As String
             Dim NAME As String
            'check the first non-space character. [ - NextArray, { - NextObject.
            If tt.Trim.StartsWith("[") Then    ' next array (list)
                Dim MASH_STEP As List = MASH_STEPS.Get("MASH_STEP")
                For Each colMASH_STEP As Map In MASH_STEP
                     STEP_TEMP= colMASH_STEP.Get("STEP_TEMP")
                      STEP_TIME = colMASH_STEP.Get("STEP_TIME")
                      INFUSE_AMOUNT = colMASH_STEP.Get("INFUSE_AMOUNT")
                      VERSION = colMASH_STEP.Get("VERSION")
                      xType = colMASH_STEP.Get("TYPE")
                      NAME = colMASH_STEP.Get("NAME")
                Next
            Else                            'next object (map)
                 Dim mMASH_STEP As Map = MASH_STEPS.Get("MASH_STEP")
                 STEP_TEMP = mMASH_STEP.Get("STEP_TEMP")
                 STEP_TIME = mMASH_STEP.Get("STEP_TIME")
                 INFUSE_AMOUNT = mMASH_STEP.Get("INFUSE_AMOUNT")
                 VERSION = mMASH_STEP.Get("VERSION")
                 xType = mMASH_STEP.Get("TYPE")
                 NAME = mMASH_STEP.Get("NAME")
            End If
 
Upvote 0
Top