static JsonDocumentBuilder UnflattenToObject(JsonElement value, IntegerTokenUnflattening options = IntegerTokenUnflattening.TryIndex) { if (value.ValueKind != JsonValueKind.Object) { throw new ArgumentException("The value to unflatten is not a JSON object"); } var result = new JsonDocumentBuilder(JsonValueKind.Object); foreach (var item in value.EnumerateObject()) { JsonDocumentBuilder part = result; JsonPointer ptr; if (!JsonPointer.TryParse(item.Name, out ptr)) { throw new ArgumentException("Name contains invalid JSON Pointer"); } var it = ptr.GetEnumerator(); bool more = it.MoveNext(); while (more) { var s = it.Current; more = it.MoveNext(); if (more) { JsonDocumentBuilder val; if (part.TryGetProperty(s, out val)) { part = val; } else { val = new JsonDocumentBuilder(JsonValueKind.Object); part.AddProperty(s,val); part = val; } } else { JsonDocumentBuilder val; if (part.TryGetProperty(s, out val)) { part = val; } else { val = new JsonDocumentBuilder(item.Value); part.AddProperty(s,val); part = val; } } } } return options == IntegerTokenUnflattening.TryIndex ? SafeUnflatten (result) : result; }
/// <summary> /// Recovers the orginal JSON value from a JSON object in flattened form, to the extent possible. /// There may not be a unique solution, an integer token in a JSON Pointer could be an array index or /// it could be an object name. The default behavior is to attempt to recover arrays. The <paramref name="options"/> /// parameter can be used to recover objects with integer names instead. /// </summary> /// <remarks> /// It is the users responsibilty to properly Dispose the returned <see cref="JsonDocument"/> value /// </remarks> /// <param name="flattenedValue">The flattened value, which must be a JSON object of name-value pairs, such that /// the names are JSON Pointer strings, and the values are either string, /// number, true, false, null, empty object, or empty array.</param> /// <param name="options">Options for handling integer tokens in the JSON Pointer.</param> /// <returns>The unflattened value</returns> /// <exception cref="ArgumentException"> /// The <paramref name="flattenedValue"/> is not a JSON object, or has a name that contains an invalid JSON pointer. /// </exception> public static JsonDocument Unflatten(JsonElement flattenedValue, IntegerTokenUnflattening options = IntegerTokenUnflattening.TryIndex) { if (options == IntegerTokenUnflattening.TryIndex) { JsonDocumentBuilder val; if (TryUnflattenArray(flattenedValue, out val)) { return val.ToJsonDocument(); } else { return UnflattenToObject(flattenedValue, options).ToJsonDocument(); } } else { return UnflattenToObject(flattenedValue, options).ToJsonDocument(); } }