Search code examples
vb.netjson.net

How can I drill into an JSON object and read an array using VB.Net


I have a JSON file:

{
  "header": {
    "type": "esummary",
    "version": "0.3"
  },
  "result": {
    "uids": [
      "3021957",
      "3202827",
      "2507140",
      "1996085"
    ],
    "3021957": {
      "uid": "3021957",
      "source": "J Pharmacol Exp Ther",
      "authors": [
        {
          "name": "Smith PH",
          "authtype": "Author",
          "clusterid": ""
        },
        {
          "name": "Jones RA",
          "authtype": "Author",
          "clusterid": ""
        }
      ],
      "volume": "239",
      "issue": "2",
      "pages": "574-83",
      "articleids": [
        {
          "idtype": "pubmed",
          "idtypen": 1,
          "value": "3021957"
        },
        {
          "idtype": "eid",
          "idtypen": 8,
          "value": "3021957"
        }
      ]
    },
    "3202827": {},
    "2507140": {}
  }
}

And my code is

Dim j As JObject = JObject.Parse(respHTML)
For Each item As JProperty In j.Item("result")
    If item.Name = "uids" Then
        Continue For
    End If
    Dim itemObjects As JToken = item
    For Each i As JObject In itemObjects
        For Each p In i
            Debug.Print(p.Key.ToString & " = " & p.Value.ToString)

            If p.Key.ToString = "authors" Then
                ' Loop Authors to concatuate them with a comma
                ' need name, name, name

            End If
            If p.Key.ToString = "source" Then
                source = p.Value.ToString
            End If
            If p.Key.ToString = "title" Then
                title = p.Value.ToString
            End If
               
            If p.Key.ToString = "articleids" Then
                ' Loop articleids to find pubmed and pmc
                'need
                '  pubmed = p.Value.ToString
                '  pmc = p.Value.ToString

            End If
        Next
    Next
    Dim testData as string = authors + " " + title + " " + source
Next

The code works fine except I don't know how to drill into the authors array or the articleids array to get the items I need. Do I build another loop or is there a better way to pull the data. I've seen a couple of other answers about JSON and they talk about building a class, would that be faster? or just cleaner code?


Solution

  • Yes, you can use loops to drill in, of course. A shorter way is to use the SelectToken and SelectTokens methods with JsonPath query expressions to extract the data you want. You can simplify your code to this:

    Dim jo As JObject = JObject.Parse(json)
    For Each prop As JProperty In jo("result")
        If prop.Name = "uids" Then
            Continue For
        End If
        Dim item As JToken = prop.Value
        Dim source As String = item("source")
        Dim title As String = item("title")
        Dim authorNames As String = String.Join(", ", item.SelectTokens("authors[*].name"))
        Dim pubmedArticleId As String = item.SelectToken("articleids[?(@.idtype == 'pubmed')].value")
        Dim pmcArticleId As String = item.SelectToken("articleids[?(@.idtype == 'pmc')].value")
    
        ' Do whatever you need to do with the above strings
    Next
    

    Here is a working demo: https://dotnetfiddle.net/urluvW