/// <summary>Removes the @preserve keywords as the last step of the framing algorithm. /// </summary> /// <remarks>Removes the @preserve keywords as the last step of the framing algorithm. /// </remarks> /// <param name="ctx">the active context used to compact the input.</param> /// <param name="input">the framed, compacted output.</param> /// <param name="options">the compaction options used.</param> /// <returns>the resulting output.</returns> /// <exception cref="JsonLdError">JsonLdError</exception> /// <exception cref="JsonLD.Core.JsonLdError"></exception> internal static JToken RemovePreserve(Context ctx, JToken input, JsonLdOptions opts ) { // recurse through arrays if (IsArray(input)) { JArray output = new JArray(); foreach (JToken i in (JArray)input) { JToken result = RemovePreserve(ctx, i, opts); // drop nulls from arrays if (!result.IsNull()) { output.Add(result); } } input = output; } else { if (IsObject(input)) { // remove @preserve if (((JObject)input).ContainsKey("@preserve")) { if (((JObject)input)["@preserve"].SafeCompare("@null")) { return(null); } return(((JObject)input)["@preserve"]); } // skip @values if (IsValue(input)) { return(input); } // recurse through @lists if (IsList(input)) { ((JObject)input)["@list"] = RemovePreserve(ctx, ((JObject)input)["@list"], opts); return(input); } // recurse through properties foreach (string prop in input.GetKeys()) { JToken result = RemovePreserve(ctx, ((JObject)input)[prop], opts ); string container = ctx.GetContainer(prop); if (opts.GetCompactArrays() && IsArray(result) && ((JArray)result).Count == 1 && container == null) { result = ((JArray)result)[0]; } ((JObject)input)[prop] = result; } } } return(input); }
/// <exception cref="JsonLdError"></exception> public static async Task <JObject> CompactAsync(JToken input, JToken context, JsonLdOptions opts) { // 1) // TODO: look into java futures/promises // 2-6) NOTE: these are all the same steps as in expand JToken expanded = await ExpandAsync(input, opts); // 7) if (context is JObject jObj && jObj.ContainsKey("@context")) { context = jObj["@context"]; } var activeCtx = await Context.ParseAsync(context, opts); // 8) var compacted = new JsonLdApi(opts).Compact(activeCtx, null, expanded, opts.GetCompactArrays ()); // final step of Compaction Algorithm // TODO: SPEC: the result result is a NON EMPTY array, if (compacted is JArray jArray) { compacted = jArray.IsEmpty() ? new JObject() : new JObject { [activeCtx.CompactIri("@graph", true)] = compacted } } ; if (!compacted.IsNull() && !context.IsNull()) { if (context is JObject && !((JObject)context).IsEmpty() || context is JArray && !((JArray)context).IsEmpty()) { compacted["@context"] = context; } } // 9) return((JObject)compacted); }
/// <summary>Removes the @preserve keywords as the last step of the framing algorithm. /// </summary> /// <remarks>Removes the @preserve keywords as the last step of the framing algorithm. /// </remarks> /// <param name="ctx">the active context used to compact the input.</param> /// <param name="input">the framed, compacted output.</param> /// <param name="options">the compaction options used.</param> /// <returns>the resulting output.</returns> /// <exception cref="JsonLdError">JsonLdError</exception> /// <exception cref="JsonLD.Core.JsonLdError"></exception> internal static JToken RemovePreserve(Context ctx, JToken input, JsonLdOptions opts ) { // recurse through arrays if (IsArray(input)) { JArray output = new JArray(); foreach (JToken i in (JArray)input) { JToken result = RemovePreserve(ctx, i, opts); // drop nulls from arrays if (!result.IsNull()) { output.Add(result); } } input = output; } else { if (IsObject(input)) { // remove @preserve if (((JObject)input).ContainsKey("@preserve")) { if (((JObject)input)["@preserve"].SafeCompare("@null")) { return null; } return ((JObject)input)["@preserve"]; } // skip @values if (IsValue(input)) { return input; } // recurse through @lists if (IsList(input)) { ((JObject)input)["@list"] = RemovePreserve(ctx, ((JObject)input)["@list"], opts); return input; } // recurse through properties foreach (string prop in input.GetKeys()) { JToken result = RemovePreserve(ctx, ((JObject)input)[prop], opts ); string container = ctx.GetContainer(prop); if (opts.GetCompactArrays() && IsArray(result) && ((JArray)result).Count == 1 && container == null) { result = ((JArray)result)[0]; } ((JObject)input)[prop] = result; } } } return input; }
/// <exception cref="JsonLD.Core.JsonLdError"></exception> public static JToken Flatten(JToken input, JToken context, JsonLdOptions opts) { // 2-6) NOTE: these are all the same steps as in expand JArray expanded = Expand(input, opts); // 7) if (context is JObject && ((IDictionary <string, JToken>)context).ContainsKey( "@context")) { context = context["@context"]; } // 8) NOTE: blank node generation variables are members of JsonLdApi // 9) NOTE: the next block is the Flattening Algorithm described in // http://json-ld.org/spec/latest/json-ld-api/#flattening-algorithm // 1) JObject nodeMap = new JObject(); nodeMap["@default"] = new JObject(); // 2) new JsonLdApi(opts).GenerateNodeMap(expanded, nodeMap); // 3) JObject defaultGraph = (JObject)JsonLD.Collections.Remove (nodeMap, "@default"); // 4) foreach (string graphName in nodeMap.GetKeys()) { JObject graph = (JObject)nodeMap[graphName]; // 4.1+4.2) JObject entry; if (!defaultGraph.ContainsKey(graphName)) { entry = new JObject(); entry["@id"] = graphName; defaultGraph[graphName] = entry; } else { entry = (JObject)defaultGraph[graphName]; } // 4.3) // TODO: SPEC doesn't specify that this should only be added if it // doesn't exists if (!entry.ContainsKey("@graph")) { entry["@graph"] = new JArray(); } JArray keys = new JArray(graph.GetKeys()); keys.SortInPlace(); foreach (string id in keys) { JObject node = (JObject)graph[id]; if (!(node.ContainsKey("@id") && node.Count == 1)) { ((JArray)entry["@graph"]).Add(node); } } } // 5) JArray flattened = new JArray(); // 6) JArray keys_1 = new JArray(defaultGraph.GetKeys()); keys_1.SortInPlace(); foreach (string id_1 in keys_1) { JObject node = (JObject)defaultGraph[id_1 ]; if (!(node.ContainsKey("@id") && node.Count == 1)) { flattened.Add(node); } } // 8) if (!context.IsNull() && !flattened.IsEmpty()) { Context activeCtx = new Context(opts); activeCtx = activeCtx.Parse(context); // TODO: only instantiate one jsonldapi JToken compacted = new JsonLdApi(opts).Compact(activeCtx, null, flattened, opts.GetCompactArrays ()); if (!(compacted is JArray)) { JArray tmp = new JArray(); tmp.Add(compacted); compacted = tmp; } string alias = activeCtx.CompactIri("@graph"); JObject rval = activeCtx.Serialize(); rval[alias] = compacted; return(rval); } return(flattened); }
/// <exception cref="JsonLD.Core.JsonLdError"></exception> public static JObject Compact(JToken input, JToken context, JsonLdOptions opts) { // 1) // TODO: look into java futures/promises // 2-6) NOTE: these are all the same steps as in expand JToken expanded = Expand(input, opts); // 7) if (context is JObject && ((IDictionary <string, JToken>)context).ContainsKey( "@context")) { context = ((JObject)context)["@context"]; } Context activeCtx = new Context(opts); activeCtx = activeCtx.Parse(context); // 8) JToken compacted = new JsonLdApi(opts).Compact(activeCtx, null, expanded, opts.GetCompactArrays ()); // final step of Compaction Algorithm // TODO: SPEC: the result result is a NON EMPTY array, if (compacted is JArray) { if (((JArray)compacted).IsEmpty()) { compacted = new JObject(); } else { JObject tmp = new JObject(); // TODO: SPEC: doesn't specify to use vocab = true here tmp[activeCtx.CompactIri("@graph", true)] = compacted; compacted = tmp; } } if (!compacted.IsNull() && !context.IsNull()) { // TODO: figure out if we can make "@context" appear at the start of // the keySet if ((context is JObject && !((JObject)context).IsEmpty()) || (context is JArray && !((JArray)context).IsEmpty())) { compacted["@context"] = context; } } // 9) return((JObject)compacted); }