[Fork] [Fork] [Fork] https://stackoverflow.com/questions/74027865/read-single-row-and-attributes-from-huge-json-file-via-jsontextreader

VbNet · Console

/Program.vb

' https://dotnetfiddle.net/Fw3myB
Imports System
Imports System.Linq
Imports System.Collections
Imports System.Collections.Generic
Imports System.IO
Imports System.Globalization
Imports System.Xml.Linq
Imports System.Xml
Imports System.Text
Imports System.Text.RegularExpressions

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json.Converters
Imports Newtonsoft.Json.Serialization

Imports NUnit.Framework

	' https://stackoverflow.com/questions/74027865/read-single-row-and-attributes-from-huge-json-file-via-jsontextreader

Public Module JsonExtensions
	Iterator Function DeserializeItemsByPath(Of T)(ByVal stream As Stream, regex as Regex, ByVal Optional settings As JsonSerializerSettings = Nothing) As IEnumerable(Of T)
		Using textReader = New StreamReader(stream, Encoding.UTF8, true, 1024, true)
			For Each item as T In DeserializeItemsByPath(Of T)(textReader, regex, settings)
				Yield item
			Next
        End Using
    End Function

	' Adapted from this answer https://stackoverflow.com/a/56411253/3744182
	' By https://stackoverflow.com/users/14357/spender
	' To https://stackoverflow.com/questions/43747477/how-to-parse-huge-json-file-as-stream-in-json-net
	Iterator Function DeserializeItemsByPath(Of T)(ByVal textReader As TextReader, ByVal regex as Regex, ByVal Optional settings As JsonSerializerSettings = Nothing) As IEnumerable(Of T)
        Dim serializer = JsonSerializer.CreateDefault(settings)
        Using reader = New JsonTextReader(textReader) With { .CloseInput = False }
            While reader.Read()
				If reader.TokenType <> JsonToken.PropertyName And regex.IsMatch(reader.Path)
                    Yield serializer.Deserialize(Of T)(reader)
                End If
            End While
        End Using
    End Function
End Module

Public Module TestClass	
	Friend Sub Test()
		TestPath(GetJson())
		Console.WriteLine()
		Test1(GetJson())
		Console.WriteLine()
		Test2(GetJson())
	End Sub

	Friend Sub TestPath(ByVal json As String)
		Dim FileName = "Question74027865.json"
		File.WriteAllText(FileName, json)

		Using textReader = New StreamReader(FileName)
		Using jsonReader = new JsonTextREader(textReader)
			Dim root = CType(JToken.Load(jsonReader), JContainer)

			Dim propertyName = "value"
			Dim actualPath = root.DescendantsAndSelf().Where(Function(t) t.Path.EndsWith(propertyName)).Select((Function(t) t.Path)).FirstOrDefault()

			Console.WriteLine("Searching for a path ending in ""{0}"" resulted in actual path ""{1}""", propertyName, actualPath)
		End Using
		End Using

		File.Delete(FileName)
	End Sub

	Friend Sub Test1(ByVal json As String)
		Dim FileName = "Question74027865.json"
		File.WriteAllText(FileName, json)

		Using stream = File.OpenRead(FileName)
			Dim regex as Regex = new Regex("^listings\[[0-9]+\]\.facilities\.totalSize\.value$", _
										   RegexOptions.CultureInvariant Or RegexOptions.Compiled Or RegexOptions.Singleline)
			Console.WriteLine(regex)
			For Each value As Decimal in JsonExtensions.DeserializeItemsByPath(Of Decimal)(stream, regex)
				Console.WriteLine("totalSize: {0}", value)
			Next
		End Using

		File.Delete(FileName)
	End Sub

	Friend Sub Test2(ByVal json As String)
		Dim FileName = "Question74027865.json"
		File.WriteAllText(FileName, json)

		Using stream = File.OpenRead(FileName)
			Dim regex as Regex = new Regex("facilities\.totalSize\.value$", _
								  		   RegexOptions.CultureInvariant Or RegexOptions.Compiled Or RegexOptions.Singleline)
			Console.WriteLine(regex)
			For Each value As Decimal in JsonExtensions.DeserializeItemsByPath(Of Decimal)(stream, regex)
				Console.WriteLine("totalSize: {0}", value)
			Next
		End Using

		File.Delete(FileName)
	End Sub

	Function GetJson() as String
		Dim Jstring As String = <![CDATA[
{
   "generatedAt":"2022-05-02 02:03:25",
   "listings":[
      {
         "countryid":1,
         "kind":1,
         "location":{
            "neighborhood":"Finthen",
            "city":"Mainz",
            "country":"Germany"
         },
         "isFocusCity":false,
         "images":null,
         "facilities":{
            "bedrooms":{
               "value":2
            },
            "totalSize":{
               "value":"100"
            }
         },
         "available":[
            {
               "from":"2022-08-05",
               "to":"2022-08-31"
            },
            {
               "from":"2023-07-01",
               "to":"9999-12-31"
            }
         ]
      },
      {
         "countryid":2,
         "kind":2,
         "location":{
            "neighborhood":"Ubers",
            "city":"NYC",
            "country":"USA"
         },
         "isFocusCity":false,
         "images":null,
         "facilities":{
            "bedrooms":{
               "value":3
            },
            "totalSize":{
               "value":"150"
            }
         },
         "available":[
            {
               "from":"2022-08-06",
               "to":"2022-09-31"
            },
            {
               "from":"2023-07-06",
               "to":"9999-12-31"
            }
         ]
      }
   ],
   "count":1077
}
]]>.Value		
		Return Jstring		
	End Function
End Module

	Public Module Module1	
		Public Sub Main()
			Console.WriteLine("Environment version: " & Environment.Version.ToString())
			Console.WriteLine("Json.NET version: " & GetType(JsonSerializer).Assembly.FullName)
            Console.WriteLine("")

			Try

				TestClass.Test()

			Catch ex as Exception

				Console.WriteLine("Unhandled exception: ")
				Console.WriteLine(ex)
				Throw

			End Try
			
		End Sub	
	End Module
;