using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public interface IJTokenWorker
bool ProcessToken<TConvertible>(JContainer parent, TConvertible index, JToken current, int depth) where TConvertible : IConvertible;
public static partial class JsonExtensions
public static void WalkTokens(this JToken root, IJTokenWorker worker, bool includeSelf = false)
throw new ArgumentNullException();
DoWalkTokens<int>(null, -1, root, worker, 0, includeSelf);
static void DoWalkTokens<TConvertible>(JContainer parent, TConvertible index, JToken current, IJTokenWorker worker, int depth, bool includeSelf) where TConvertible : IConvertible
if (!worker.ProcessToken(parent, index, current, depth))
var currentAsContainer = current as JContainer;
if (currentAsContainer != null)
IList<JToken> currentAsList = currentAsContainer;
for (int i = 0; i < currentAsList.Count; i++)
var child = currentAsList[i];
DoWalkTokens(currentAsContainer, ((JProperty)child).Name, ((JProperty)child).Value, worker, depth+1, true);
DoWalkTokens(currentAsContainer, i, child, worker, depth+1, true);
static JmesPath jmes = new JmesPath();
public static void Test()
string policyStr = GetJson();
Test(GetComplexTestJson());
static void Test(string policyStr)
string str = jmes.Transform(policyStr, "properties.policyRule.if");
Console.WriteLine("Input JSON:");
Console.WriteLine(JToken.Parse(str));
Console.WriteLine("\nJSON dump:");
static string GetComplexTestJson()
""displayName"": ""Audit if Key Vault has no virtual network rules"",
""policyType"": ""Custom"",
""description"": ""Audits Key Vault vaults if they do not have virtual network service endpoints set up. More information on virtual network service endpoints in Key Vault is available here: _https://docs.microsoft.com/en-us/azure/key-vault/key-vault-overview-vnet-service-endpoints"",
""category"": ""Key Vault"",
""array"": [1, 2, ""3"", 4, { ""aa"" : [""bb""]}, ""z""],
""JConstructor example"": new Something(1, 2, 3),
""equals"": ""Microsoft.KeyVault/vaults""
""field"": ""Microsoft.KeyVault/vaults/networkAcls.virtualNetworkRules[*].id"",
""field"": ""Microsoft.KeyVault/vaults/networkAcls.virtualNetworkRules[*].id"",
""field"": ""Microsoft.KeyVault/vaults/networkAcls.defaultAction"",
""id"": ""/subscriptions/xxxxxx/providers/Microsoft.Authorization/policyDefinitions/wkpolicydef"",
""type"": ""Microsoft.Authorization/policyDefinitions"",
""displayName"": ""Audit if Key Vault has no virtual network rules"",
""policyType"": ""Custom"",
""description"": ""Audits Key Vault vaults if they do not have virtual network service endpoints set up. More information on virtual network service endpoints in Key Vault is available here: _https://docs.microsoft.com/en-us/azure/key-vault/key-vault-overview-vnet-service-endpoints"",
""category"": ""Key Vault"",
""equals"": ""Microsoft.KeyVault/vaults""
""field"": ""Microsoft.KeyVault/vaults/networkAcls.virtualNetworkRules[*].id"",
""field"": ""Microsoft.KeyVault/vaults/networkAcls.virtualNetworkRules[*].id"",
""field"": ""Microsoft.KeyVault/vaults/networkAcls.defaultAction"",
""id"": ""/subscriptions/xxxxxx/providers/Microsoft.Authorization/policyDefinitions/wkpolicydef"",
""type"": ""Microsoft.Authorization/policyDefinitions"",
class JTokenPrinter : IJTokenWorker
public bool ProcessToken<TConvertible>(JContainer parent, TConvertible index, JToken current, int depth) where TConvertible : IConvertible
var spacer = new String('\t', depth);
if (parent != null && index is int)
name = string.Format("[{0}]", index);
else if (parent != null && index != null)
val = ((JValue)current).ToString();
else if (current is JConstructor)
val = "new " + ((JConstructor)current).Name;
Console.WriteLine(string.Format("{0}{1} -> {2}", spacer, name, val));
public static void Convert(string json)
var root = JsonConvert.DeserializeObject<JToken>(json);
root.WalkTokens(new JTokenPrinter());
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");