Reputation: 378
{"a":1,"b":{"c":{}},"d":{"e":1,"f":{"g":{}}}}
This is a simple json,how to recursively delete empty keys from json so output should be here
{"a":1,"d":{"e":1}}
The thing i tried removeEmptyDocs(token,"{}")
private void removeEmptyDocs(JToken token, string empty)
{
JContainer container = token as JContainer;
if (container == null) return;
List<JToken> removeList = new List<JToken>();
foreach (JToken el in container.Children())
{
JProperty p = el as JProperty;
if (p != null && empty.Contains(p.Value.ToString()))
{
removeList.Add(el);
}
removeEmptyDocs(el, empty);
}
foreach (JToken el in removeList)
{
el.Remove();
}
}
Upvotes: 1
Views: 2097
Reputation: 525
You can't remove tokens while iterating, so you should do it after all empty leaves are collected. Here is the code, it's not optimal, but rather good point to start from. And it it does what's expected
class Program
{
static void Main(string[] args)
{
var json =
"{'a': 1, 'b': {'c': {}, k: [], z: [1, 3]},'d': {'e': 1,'f': {'g': {}}}}";
var parsed = (JContainer)JsonConvert.DeserializeObject(json);
var nodesToDelete = new List<JToken>();
do
{
nodesToDelete.Clear();
ClearEmpty(parsed, nodesToDelete);
foreach (var token in nodesToDelete)
{
token.Remove();
}
} while (nodesToDelete.Count > 0);
}
private static void ClearEmpty(JContainer container, List<JToken> nodesToDelete)
{
if (container == null) return;
foreach (var child in container.Children())
{
var cont = child as JContainer;
if (child.Type == JTokenType.Property ||
child.Type == JTokenType.Object ||
child.Type == JTokenType.Array)
{
if (child.HasValues)
{
ClearEmpty(cont, nodesToDelete);
}
else
{
nodesToDelete.Add(child.Parent);
}
}
}
}
}
Upvotes: 2