using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class NameRemappingJsonWriter : JsonTextWriter
readonly Func<string, int, string, string> map;
public NameRemappingJsonWriter(TextWriter textWriter, Func<string, int, string, string> map) : base(textWriter)
throw new ArgumentNullException(nameof(map));
public override void WritePropertyName(string name)
base.WritePropertyName(map(name, Top, Path));
public override void WritePropertyName(string name, bool escape)
base.WritePropertyName(map(name, Top, Path), escape);
public static partial class JsonExtensions
public static void StreamRenameJsonProperties(string inFilePath, string outFilePath, string oldName, Regex parentPathRegex, string newName, Formatting formatting = Formatting.Indented)
Func<string, int, string, string> map = (name, depth, parentPath) =>
if (name == oldName && parentPathRegex.IsMatch(parentPath))
StreamRenameJsonProperties(inFilePath, outFilePath, map, formatting);
public static void StreamRenameJsonProperties(string inFilePath, string outFilePath, Func<string, int, string, string> map, Formatting formatting = Formatting.Indented)
using (var textReader = new StreamReader(inFilePath))
using (var jsonReader = new JsonTextReader(textReader) { DateParseHandling = DateParseHandling.None })
using (var textWriter = new StreamWriter(outFilePath))
using (var jsonWriter = new NameRemappingJsonWriter(textWriter, map) { Formatting = formatting })
jsonWriter.WriteToken(jsonReader);
public static void Test()
var inPath = "Question58931339.Input.json";
var outPath = "Question58931339.Output.json";
File.WriteAllText(inPath, GetJson());
Console.WriteLine("Output JSON:");
Console.WriteLine(File.ReadAllText(outPath));
static void Test(string inFilePath, string outFilePath, Formatting formatting = Formatting.Indented)
JsonExtensions.StreamRenameJsonProperties(inFilePath, outFilePath, "name", new Regex("profiles\\[[0-9]+\\]$"), "profileName");
""name"": ""profile 1.1""
""name"": ""profile 1.2""
""name"": ""profile 2.1""
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];
So is your question, *How can I rename the properties `..profiles[*].name` to `..profiles[*].profileName`using some sort of streaming transformation, without loading the entire JSON into memory?*
Because you can do it easily with [tag:json.net] if you load the entire thing into memory, see https: