using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
""Description"": ""This is the ${root} of the ${tree}."",
""Description"": ""This is first ${child} of the ${root}."",
""Description"": ""Some ${node}s in the ${tree} are deeply nested, like this one."",
""Description"": ""They say money is the ${root} of all evil."",
""Description"": ""This is the second ${child} of the ${root}"",
""Description"": ""You wouldn't want to chop down this ${tree}."",
""Description"": ""This ${root} of the ${tree} is two levels below this ${node}."",
Dictionary<string, string> placeholders = new Dictionary<string, string>
{ "${root}", "bottom-most ${node}" },
{ "${child}", "immediate descendant ${node}" },
{ "${tree}", "hierarchy" },
JContainer root = (JContainer)JToken.Parse(json);
ReplacePlaceholderValues(root, placeholders);
Console.WriteLine(root.ToString());
public static void ReplacePlaceholderValues(JContainer root, Dictionary<string, string> placeholders)
var jValues = root.Descendants()
.Where(jv => jv.Type == JTokenType.String);
foreach (var jVal in jValues)
jVal.Value = ReplacePlaceholderValues((string)jVal.Value, placeholders);
public static string ReplacePlaceholderValues(string source, Dictionary<string, string> placeholders)
var replacedText = placeholders.Aggregate(source, (current, replacement) =>
return current.Replace(replacement.Key, replacement.Value);