Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解析包含多个JSON对象的文件,这些对象由空行或制表符分隔_Json_Vb.net_Json.net - Fatal编程技术网

解析包含多个JSON对象的文件,这些对象由空行或制表符分隔

解析包含多个JSON对象的文件,这些对象由空行或制表符分隔,json,vb.net,json.net,Json,Vb.net,Json.net,我在这里无法正确解析JSON。我使用以下格式并尝试使用JObjects,但它所做的是将一个对象拆分为不同的对象。也许有一个例子是有意义的: { "completed_in": 0.012, "max_id": 136536013832069120, "max_id_str": "136536013832069120", "next_page": "?page=2&max_id=136536013832069120&q=twitterapi&rpp=1",

我在这里无法正确解析JSON。我使用以下格式并尝试使用JObjects,但它所做的是将一个对象拆分为不同的对象。也许有一个例子是有意义的:

{
  "completed_in": 0.012,
  "max_id": 136536013832069120,
  "max_id_str": "136536013832069120",
  "next_page": "?page=2&max_id=136536013832069120&q=twitterapi&rpp=1",
  "page": 1,
  "query": "twitterapi",
  "refresh_url": "?since_id=136536013832069120&q=twitterapi",
  "results": [
  {
  "created_at": "Tue, 15 Nov 2011 20:08:17 +0000",
  "from_user": "fakekurrik",
  "from_user_id": 370773112,
  "from_user_id_str": "370773112",
  "from_user_name": "fakekurrik",
  "geo": null,
  "id": 136536013832069120,
  "id_str": "136536013832069120",
  "iso_language_code": "en",
  "metadata": {
    "result_type": "recent"
  },
  "profile_image_url": "http://a1.twimg.com/profile_images/1540298033/phatkicks_normal.jpg",
  "source": "<a href="http://twitter.com/">web</a>",
  "text": "@twitterapi, keep on keeping it real",
  "to_user": "twitterapi",
  "to_user_id": 6253282,
  "to_user_id_str": "6253282",
  "to_user_name": "Twitter API"
  }
],
"results_per_page": 1,
 "since_id": 0,
 "since_id_str": "0"
}
这就是我所考虑的一个目标。我有数百个这样的文件,它们之间用一个制表符或空行隔开。现在如果我使用JObject

   Dim jobj As JObject = JObject.Parse(txtStuff.ToString())

    Dim results As List(Of JToken) = jobj.Children().ToList

结果包含所有单个标记。我如何才能将上述每个对象(整个对象)放入一个要处理的列表中?

听起来您在这里真的要问两个问题

  • 考虑到上面的JSON,如何将数据转换成一个好的对象结构
  • 考虑到我有很多包含这些对象的文件,如何将它们放入列表中
  • 第一部分很简单。只需定义一个与JSON匹配的类结构,然后使用
    JsonConvert.DeserializeObject()
    将JSON反序列化为该对象。对于您发布的JSON,类结构如下所示:

    Class RootObject
        Public Property completed_in As Double
        Public Property max_id As Long
        Public Property max_id_str As String
        Public Property next_page As String
        Public Property page As Integer
        Public Property query As String
        Public Property refresh_url As String
        Public Property results As List(Of Result)
        Public Property results_per_page As Integer
        Public Property since_id As Integer
        Public Property since_id_str As String
    End Class
    
    Class Result
        Public Property created_at As String
        Public Property from_user As String
        Public Property from_user_id As Integer
        Public Property from_user_id_str As String
        Public Property from_user_name As String
        Public Property geo As Object
        Public Property id As Long
        Public Property id_str As String
        Public Property iso_language_code As String
        Public Property metadata As Metadata
        Public Property profile_image_url As String
        Public Property source As String
        Public Property text As String
        Public Property to_user As String
        Public Property to_user_id As Integer
        Public Property to_user_id_str As String
        Public Property to_user_name As String
    End Class
    
    Class Metadata
        Public Property result_type As String
    End Class
    
    Dim obj As String = JsonConvert.DeserializeObject(Of RootObject)(json)
    
    您可以按如下方式对其进行反序列化:

    Class RootObject
        Public Property completed_in As Double
        Public Property max_id As Long
        Public Property max_id_str As String
        Public Property next_page As String
        Public Property page As Integer
        Public Property query As String
        Public Property refresh_url As String
        Public Property results As List(Of Result)
        Public Property results_per_page As Integer
        Public Property since_id As Integer
        Public Property since_id_str As String
    End Class
    
    Class Result
        Public Property created_at As String
        Public Property from_user As String
        Public Property from_user_id As Integer
        Public Property from_user_id_str As String
        Public Property from_user_name As String
        Public Property geo As Object
        Public Property id As Long
        Public Property id_str As String
        Public Property iso_language_code As String
        Public Property metadata As Metadata
        Public Property profile_image_url As String
        Public Property source As String
        Public Property text As String
        Public Property to_user As String
        Public Property to_user_id As Integer
        Public Property to_user_id_str As String
        Public Property to_user_name As String
    End Class
    
    Class Metadata
        Public Property result_type As String
    End Class
    
    Dim obj As String = JsonConvert.DeserializeObject(Of RootObject)(json)
    
    因此,此时,
    obj
    将包含来自一个对象的所有数据,正如您在问题中定义的那样。现在,您已经指出,您有一个文件,其中包含许多JSON对象,这些对象由一个选项卡或一个空行分隔。您不能仅仅读取整个文件并将其作为一个大字符串提供给JSON解析器,因为这种格式不是有效的JSON。(当然,每个单独的对象都是有效的JSON,但是当与制表符或空行分隔符串在一起时,整个对象是无效的。)因此,您需要逐行(或者可能是逐字符)读取文件以找到分隔符,并将其分解为解析器可以理解的有效JSON对象。每次找到一个分隔符时,获取自上一个分隔符以来读取的所有数据,并将其提供给反序列化程序。每次反序列化的结果都将是一个有效的
    RootObject
    ,您可以在执行时将其添加到列表中

    下面是一些代码,让您了解这可能是如何工作的。根据你的需要,你可能需要对它进行调整,但我猜这离目标不远

    '' This function will read a file containing a series of JSON objects separated by 
    '' some string that is NOT part of the JSON.  Could be a blank line or a tab or 
    '' something else.  It will return a list of the deserialized JSON objects.
    '' This function relies on two other helper functions (below).
    Function ReadJsonFile(fileName As String, separator As String) As List(Of RootObject)
        Dim objects As New List(Of RootObject)
        Using sr As New StreamReader(fileName)
            Dim json As String
            Do
                json = ReadToSeparator(sr, separator)
                If json.Length > 0 Then
                    objects.Add(JsonConvert.DeserializeObject(Of RootObject)(json))
                End If
            Loop Until json.Length = 0
        End Using
        Return objects
    End Function
    
    '' This function will read and build up a string until the given separator is found.
    '' Once the separator is found, it returns the string with the separator removed.
    '' If no separator is found before the end of the data is reached, it returns
    '' whatever was read to that point.
    Function ReadToSeparator(reader As TextReader, separator As String) As String
        Dim sb As New StringBuilder()
        While reader.Peek <> -1
            Dim ch As Char = ChrW(reader.Read())
            sb.Append(ch)
            If TailMatchesSeparator(sb, separator) Then
                sb.Remove(sb.Length - separator.Length, separator.Length)
                Exit While
            End If
        End While
        Return sb.ToString()
    End Function
    
    '' This function checks whether the last characters in a StringBuffer match the
    '' given separator string.  Returns true if so or false if not.
    Function TailMatchesSeparator(sb As StringBuilder, separator As String) As Boolean
        If sb.Length >= separator.Length Then
            Dim i As Integer = sb.Length - 1
            For j As Integer = separator.Length - 1 To 0 Step -1
                If sb(i) <> separator(j) Then
                    Return False
                End If
                i = i - 1
            Next
            Return True
        End If
        Return False
    End Function
    

    感谢您花时间回复并给出详细答案。我很感激。是的,因为我的帖子,我搜索并尝试了多个选项,但找不到json.net soln,它只会按照我的意愿拆分对象,并且发现反序列化它将是最佳选择。然后我犯了一个错误,没有为每个字段定义类结构,但是您提供的内容肯定会有所帮助。谢谢