Click here to Skip to main content
15,443,549 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
HI, I have a file API2.txt that contain the following:
XML
{
    "results": [{
        "rating2": 6.66666,
        "downloads_min": 5000000,
        "klm": [{
            "top1": "mine"
        },
        {
            "top2": "yours"
        }]
    },
    {
        "rating2": 4.4444,
        "downloads_min": 505550000,
        "klm": [{
            "top1": "2mine"
        },
        {
            "top2": "2yours"
        }]
    },
    {
        "rating2": 900000,
        "downloads_min": 505550000,
        "klm": [{
            "top1": "mine"
        },
        {
            "top2": "yours"
        }]
    }],
    "number_results": 263,
    "has_next": true,
    "page": 1,
    "num_pages": 132,
    "limit": 2
}


I can get the value of any keys except "top1" and "top2". how can I get the value for "top1" and "top2"? I am using the following code to extract:

What I have tried:

VB
Dim value As String = File.ReadAllText("C:\Farmers\API\API2.txt")
Dim json As JObject = JObject.Parse(value)

For Each Row2 In json("results").ToList()
    Response.Write(Row2("rating2").ToString() & "<br>")
Next
Response.Write(json("number_results"))
Posted
Updated 4-Apr-20 8:19am
v2

I have a helper function for pulling data from JSON that I use in my article: Working with JSON in C# & VB[^]
VB
Imports Newtonsoft.Json.Linq

Public Module JsonExtensions

    <Extension>
    Public Function FindTokens(containerToken As JToken, name As String) _
                        As List(Of JToken)

        Dim matches = New List(Of JToken)()
        FindTokens(containerToken, name, matches)
        Return matches

    End Function

    Private Sub FindTokens(containerToken As JToken, name As String, _
                           matches As List(Of JToken))

        If containerToken.Type = JTokenType.[Object] Then
            For Each child As JProperty In containerToken.Children(Of JProperty)()
                If child.Name = name Then
                    matches.Add(child.Value)
                End If
                FindTokens(child.Value, name, matches)
            Next
        ElseIf containerToken.Type = JTokenType.Array Then
            For Each child As JToken In containerToken.Children()
                FindTokens(child, name, matches)
            Next
        End If

    End Sub

End Module

Then to use, you simply do something like::
VB
Dim tags As List(Of Single) = _
    JObject.Parse(rawJSON) _
           .FindTokens("rating2") _
           .Values(Of Single)() _
           .ToList()

UPDATE: Here is a full example for you that you can plug into a test console app:
VB
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json.Linq

Module Module1

    Sub Main()

        Dim rawJSON = "{
            ""results"": [{
                ""rating2"": 6.66666,
                ""downloads_min"": 5000000,
                ""klm"": [{
                    ""top1"": ""mine""
                },
                {
                    ""top2"": ""yours""
                }]
            },
            {
                ""rating2"": 4.4444,
                ""downloads_min"": 505550000,
                ""klm"": [{
                    ""top1"": ""2mine""
                },
                {
                    ""top2"": ""2yours""
                }]
            },
            {
                ""rating2"": 900000,
                ""downloads_min"": 505550000,
                ""klm"": [{
                    ""top1"": ""mine""
                },
                {
                    ""top2"": ""yours""
                }]
            }],
            ""number_results"": 263,
            ""has_next"": true,
            ""page"": 1,
            ""num_pages"": 132,
            ""limit"": 2
        }"

        Dim tags As List(Of Single) =
            JObject.Parse(rawJSON) _
                   .FindTokens("rating2") _
                   .Values(Of Single)() _
                   .ToList()

        For Each tag In tags
            Console.WriteLine(tag)
        Next

    End Sub

End Module

Public Module JsonExtensions

    <Extension>
    Public Function FindTokens(containerToken As JToken, name As String) _
                        As List(Of JToken)

        Dim matches = New List(Of JToken)()
        FindTokens(containerToken, name, matches)
        Return matches

    End Function

    Private Sub FindTokens(containerToken As JToken, name As String,
                           matches As List(Of JToken))

        If containerToken.Type = JTokenType.[Object] Then
            For Each child As JProperty In containerToken.Children(Of JProperty)()
                If child.Name = name Then
                    matches.Add(child.Value)
                End If
                FindTokens(child.Value, name, matches)
            Next
        ElseIf containerToken.Type = JTokenType.Array Then
            For Each child As JToken In containerToken.Children()
                FindTokens(child, name, matches)
            Next
        End If

    End Sub

End Module

And the output is:
6.66666
4.4444
900000
 
Share this answer
 
v3
Comments
[no name] 23-Mar-20 12:15pm    
I tried this your code but its not giving me any result. my app is kind of different from this i am just using your json helper but its not working. i was tthinking i could use it to extract just anything
Graeme_Grant 24-Mar-20 3:14am    
It depends on how you are using it. This is a closed question, so you will need to post a new one.
Thanks for the reply. But I keep getting:
FindTokens is not member of Newtonsoft.Json.Linq.


I am not sure what I am doing wrong. The deserializtion is from a button click event.
so when I call the FindTokens function I get that error.

Thanks,
 
Share this answer
 
Comments
Richard Deeming 23-Feb-18 9:27am    
If you want to reply to a solution, click the "Reply" button under the solution. DO NOT post your comment as a new "solution".
Graeme_Grant 23-Feb-18 10:57am     CRLF
Works fine. Please note that I am using an extension method. If you do not correctly add it to your app you will see that error message as you describe. See update to solution 1 with a full copy and paste version for a console app.
jameskm69 26-Feb-18 9:26am    
Thanks for your reply post. Yes it is working. Thanks again
   Imports System.Web.Script.Serialization

   Structure JSONStruct
    Structure resultsStruct
        Structure klmStruct
            Public top1 As String
            Public top2 As String
        End Structure
        Public rating2 As Decimal
        Public downloads_min As Integer
        Public klm As List(Of klmStruct)
    End Structure
    Public results As List(Of resultsStruct)
    Public number_results As Integer
    Public has_next As Boolean
    Public page As Integer
    Public num_pages As Integer
    Public limit As Integer
End Structure
Function test()

    Dim serializer As New JavaScriptSerializer

    Dim rawJSON = "{
        ""results"": [{
            ""rating2"": 6.66666,
            ""downloads_min"": 5000000,
            ""klm"": [{
                ""top1"": ""mine""
            },
            {
                ""top2"": ""yours""
            }]
        },
        {
            ""rating2"": 4.4444,
            ""downloads_min"": 505550000,
            ""klm"": [{
                ""top1"": ""2mine""
            },
            {
                ""top2"": ""2yours""
            }]
        },
        {
            ""rating2"": 900000,
            ""downloads_min"": 505550000,
            ""klm"": [{
                ""top1"": ""mine""
            },
            {
                ""top2"": ""yours""
            }]
        }],
        ""number_results"": 263,
        ""has_next"": true,
        ""page"": 1,
        ""num_pages"": 132,
        ""limit"": 2
    }"

    Dim json As JSONStruct = serializer.Deserialize(Of JSONStruct)(rawJSON)

    For Each result As JSONStruct.resultsStruct In json.results

        For Each klm As JSONStruct.resultsStruct.klmStruct In result.klm
            If klm.top1 IsNot Nothing Then
                Console.WriteLine(klm.top1)
            End If
            If klm.top2 IsNot Nothing Then
                Console.WriteLine(klm.top2)
            End If
        Next

    Next
End Function


output:
mine
yours
2mine
2yours
mine
yours
 
Share this answer
 
Comments
CHill60 6-Apr-20 6:51am    
Where is the output for top1 and top2 that the OP required?
Member 14792456 6-Apr-20 9:52am    
Right under the words output:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900