/// <summary>Parses RDF in the form of N-Quads.</summary> /// <remarks>Parses RDF in the form of N-Quads.</remarks> /// <param name="input">the N-Quads input to parse.</param> /// <returns>an RDF dataset.</returns> /// <exception cref="JsonLD.Core.JsonLdError"></exception> public static RDFDataset ParseNQuads(string input) { // build RDF dataset RDFDataset dataset = new RDFDataset(); // split N-Quad input into lines string[] lines = RDFDatasetUtils.Regex.Eoln.Split(input); int lineNumber = 0; foreach (string line in lines) { lineNumber++; // skip empty lines if (RDFDatasetUtils.Regex.EmptyOrComment.Matcher(line).Matches()) { continue; } // parse quad Matcher match = RDFDatasetUtils.Regex.Quad.Matcher(line); if (!match.Matches()) { throw new JsonLdError(JsonLdError.Error.SyntaxError, "Error while parsing N-Quads; invalid quad. line:" + lineNumber); } // get subject RDFDataset.Node subject; if (match.Group(1) != null) { var subjectIri = Unescape(match.Group(1)); AssertAbsoluteIri(subjectIri); subject = new RDFDataset.IRI(subjectIri); } else { subject = new RDFDataset.BlankNode(Unescape(match.Group(2))); } // get predicate var predicateIri = Unescape(match.Group(3)); AssertAbsoluteIri(predicateIri); RDFDataset.Node predicate = new RDFDataset.IRI(predicateIri); // get object RDFDataset.Node @object; if (match.Group(4) != null) { var objectIri = Unescape(match.Group(4)); AssertAbsoluteIri(objectIri); @object = new RDFDataset.IRI(objectIri); } else { if (match.Group(5) != null) { @object = new RDFDataset.BlankNode(Unescape(match.Group(5))); } else { string language = Unescape(match.Group(8)); string datatype = match.Group(7) != null?Unescape(match.Group(7)) : match.Group (8) != null ? JSONLDConsts.RdfLangstring : JSONLDConsts.XsdString; AssertAbsoluteIri(datatype); string unescaped = Unescape(match.Group(6)); @object = new RDFDataset.Literal(unescaped, datatype, language); } } // get graph name ('@default' is used for the default graph) string name = "@default"; if (match.Group(9) != null) { name = Unescape(match.Group(9)); AssertAbsoluteIri(name); } else { if (match.Group(10) != null) { name = Unescape(match.Group(10)); } } RDFDataset.Quad triple = new RDFDataset.Quad(subject, predicate, @object, name); // initialise graph in dataset if (!dataset.ContainsKey(name)) { IList <RDFDataset.Quad> tmp = new List <RDFDataset.Quad>(); tmp.Add(triple); dataset[name] = tmp; } else { // add triple if unique to its graph IList <RDFDataset.Quad> triples = (IList <RDFDataset.Quad>)dataset[name]; if (!triples.Contains(triple)) { triples.Add(triple); } } } return(dataset); }
/// <summary>Creates an array of RDF triples for the given graph.</summary> /// <remarks>Creates an array of RDF triples for the given graph.</remarks> /// <param name="graph">the graph to create RDF triples for.</param> internal virtual void GraphToRDF(string graphName, JObject graph ) { // 4.2) IList <RDFDataset.Quad> triples = new List <RDFDataset.Quad>(); // 4.3) IEnumerable <string> subjects = graph.GetKeys(); // Collections.sort(subjects); foreach (string id in subjects) { if (JsonLdUtils.IsRelativeIri(id)) { continue; } JObject node = (JObject)graph[id]; JArray properties = new JArray(node.GetKeys()); properties.SortInPlace(); foreach (string property in properties) { var localProperty = property; JArray values; // 4.3.2.1) if ("@type".Equals(localProperty)) { values = (JArray)node["@type"]; localProperty = JSONLDConsts.RdfType; } else { // 4.3.2.2) if (JsonLdUtils.IsKeyword(localProperty)) { continue; } else { // 4.3.2.3) if (localProperty.StartsWith("_:") && !api.opts.GetProduceGeneralizedRdf()) { continue; } else { // 4.3.2.4) if (JsonLdUtils.IsRelativeIri(localProperty)) { continue; } else { values = (JArray)node[localProperty]; } } } } RDFDataset.Node subject; if (id.IndexOf("_:") == 0) { // NOTE: don't rename, just set it as a blank node subject = new RDFDataset.BlankNode(id); } else { subject = new RDFDataset.IRI(id); } // RDF predicates RDFDataset.Node predicate; if (localProperty.StartsWith("_:")) { predicate = new RDFDataset.BlankNode(localProperty); } else { predicate = new RDFDataset.IRI(localProperty); } foreach (JToken item in values) { // convert @list to triples if (JsonLdUtils.IsList(item)) { JArray list = (JArray)((JObject)item)["@list"]; RDFDataset.Node last = null; RDFDataset.Node firstBNode = nil; if (!list.IsEmpty()) { last = ObjectToRDF(list[list.Count - 1]); firstBNode = new RDFDataset.BlankNode(api.GenerateBlankNodeIdentifier()); } triples.Add(new RDFDataset.Quad(subject, predicate, firstBNode, graphName)); for (int i = 0; i < list.Count - 1; i++) { RDFDataset.Node @object = ObjectToRDF(list[i]); triples.Add(new RDFDataset.Quad(firstBNode, first, @object, graphName)); RDFDataset.Node restBNode = new RDFDataset.BlankNode(api.GenerateBlankNodeIdentifier ()); triples.Add(new RDFDataset.Quad(firstBNode, rest, restBNode, graphName)); firstBNode = restBNode; } if (last != null) { triples.Add(new RDFDataset.Quad(firstBNode, first, last, graphName)); triples.Add(new RDFDataset.Quad(firstBNode, rest, nil, graphName)); } } else { // convert value or node object to triple RDFDataset.Node @object = ObjectToRDF(item); if (@object != null) { triples.Add(new RDFDataset.Quad(subject, predicate, @object, graphName)); } } } } } this[graphName] = triples; }