public void WritingCollectionCompressionEmpty2() { Graph g = new Graph(); g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/")); INode rdfType = g.CreateUriNode("rdf:type"); g.Assert(g.CreateUriNode("ex:subj"), g.CreateUriNode("ex:pred"), g.CreateUriNode("rdf:nil")); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Assert.AreEqual(0, context.Collections.Count, "Expected 0 Collection to be found"); this.CheckCompressionRoundTrip(g); }
/// <summary> /// Generates Output for Triples as a single "s p o." Triple /// </summary> /// <param name="context">Writer Context</param> /// <param name="t">Triple to output</param> /// <returns></returns> /// <remarks>Used only in High Speed Write Mode</remarks> private String GenerateTripleOutput(CompressingTurtleWriterContext context, Triple t) { StringBuilder temp = new StringBuilder(); temp.Append(this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject, 0)); temp.Append(' '); temp.Append(this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate, 0)); temp.Append(' '); temp.Append(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object, 0)); temp.Append('.'); return temp.ToString(); }
/// <summary> /// Generates the Turtle Syntax for the Graph /// </summary> private void GenerateOutput(CompressingTurtleWriterContext context) { //Create the Header //Base Directive if (context.Graph.BaseUri != null) { context.Output.WriteLine("@base <" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">."); context.Output.WriteLine(); } //Prefix Directives foreach (String prefix in context.Graph.NamespaceMap.Prefixes) { if (TurtleSpecsHelper.IsValidQName(prefix + ":")) { if (!prefix.Equals(String.Empty)) { context.Output.WriteLine("@prefix " + prefix + ": <" + context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(prefix)) + ">."); } else { context.Output.WriteLine("@prefix : <" + context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(String.Empty)) + ">."); } } } context.Output.WriteLine(); //Decide on the Write Mode to use bool hiSpeed = false; double subjNodes = context.Graph.Triples.SubjectNodes.Count(); double triples = context.Graph.Triples.Count; if ((subjNodes / triples) > 0.75) hiSpeed = true; if (context.CompressionLevel == WriterCompressionLevel.None || (hiSpeed && context.HighSpeedModePermitted)) { this.RaiseWarning("High Speed Write Mode in use - minimal syntax compression will be used"); context.CompressionLevel = WriterCompressionLevel.Minimal; context.NodeFormatter = new UncompressedTurtleFormatter(); foreach (Triple t in context.Graph.Triples) { context.Output.WriteLine(this.GenerateTripleOutput(context, t)); } } else { if (context.CompressionLevel >= WriterCompressionLevel.More) { WriterHelper.FindCollections(context); } //Get the Triples as a Sorted List List<Triple> ts = context.Graph.Triples.Where(t => !context.TriplesDone.Contains(t)).ToList(); ts.Sort(); //Variables we need to track our writing INode lastSubj, lastPred; lastSubj = lastPred = null; int subjIndent = 0, predIndent = 0; String temp; for (int i = 0; i < ts.Count; i++) { Triple t = ts[i]; if (lastSubj == null || !t.Subject.Equals(lastSubj)) { //Terminate previous Triples if (lastSubj != null) context.Output.WriteLine("."); //Start a new set of Triples temp = this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject, 0); context.Output.Write(temp); context.Output.Write(" "); if (temp.Contains('\n')) { subjIndent = temp.Split('\n').Last().Length + 1; } else { subjIndent = temp.Length + 1; } lastSubj = t.Subject; //Write the first Predicate temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate, subjIndent); context.Output.Write(temp); context.Output.Write(" "); predIndent = temp.Length + 1; lastPred = t.Predicate; } else if (lastPred == null || !t.Predicate.Equals(lastPred)) { //Terminate previous Predicate Object list context.Output.WriteLine(";"); if (context.PrettyPrint) context.Output.Write(new String(' ', subjIndent)); //Write the next Predicate temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate, subjIndent); context.Output.Write(temp); context.Output.Write(" "); predIndent = temp.Length + 1; lastPred = t.Predicate; } else { //Continue Object List context.Output.WriteLine(","); if (context.PrettyPrint) context.Output.Write(new String(' ', subjIndent + predIndent)); } //Write the Object context.Output.Write(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object, subjIndent + predIndent)); } //Terminate Triples if (ts.Count > 0) context.Output.WriteLine("."); return; } }
/// <summary> /// Generates Output for Nodes in Turtle syntax /// </summary> /// <param name="context">Writer Context</param> /// <param name="n">Node to generate output for</param> /// <param name="segment">Segment of the Triple being written</param> /// <param name="indent">Indentation</param> /// <returns></returns> private String GenerateNodeOutput(CompressingTurtleWriterContext context, INode n, TripleSegment segment, int indent) { StringBuilder output = new StringBuilder(); switch (n.NodeType) { case NodeType.Blank: if (segment == TripleSegment.Predicate) throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("Turtle")); if (context.Collections.ContainsKey(n)) { output.Append(this.GenerateCollectionOutput(context, context.Collections[n], indent)); } else { return context.NodeFormatter.Format(n, segment); } break; case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("Turtle")); case NodeType.Literal: if (segment == TripleSegment.Subject) throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("Turtle")); if (segment == TripleSegment.Predicate) throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("Turtle")); return context.NodeFormatter.Format(n, segment); case NodeType.Uri: return context.NodeFormatter.Format(n, segment); default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("Turtle")); } return output.ToString(); }
/// <summary> /// Internal Helper method which converts a Collection into Turtle Syntax /// </summary> /// <param name="context">Writer Context</param> /// <param name="c">Collection to convert</param> /// <param name="indent">Indentation</param> /// <returns></returns> private String GenerateCollectionOutput(CompressingTurtleWriterContext context, OutputRdfCollection c, int indent) { StringBuilder output = new StringBuilder(); bool first = true; if (!c.IsExplicit) { output.Append('('); while (c.Triples.Count > 0) { if (context.PrettyPrint && !first) output.Append(new String(' ', indent)); first = false; output.Append(this.GenerateNodeOutput(context, c.Triples.First().Object, TripleSegment.Object, indent)); c.Triples.RemoveAt(0); if (c.Triples.Count > 0) { output.Append(' '); } } output.Append(')'); } else { if (c.Triples.Count == 0) { //Empty Collection //Can represent as a single Blank Node [] output.Append("[]"); } else { output.Append('['); while (c.Triples.Count > 0) { if (context.PrettyPrint && !first) output.Append(new String(' ', indent)); first = false; String temp = this.GenerateNodeOutput(context, c.Triples.First().Predicate, TripleSegment.Predicate, indent); output.Append(temp); output.Append(' '); int addIndent; if (temp.Contains('\n')) { addIndent = temp.Split('\n').Last().Length; } else { addIndent = temp.Length; } output.Append(this.GenerateNodeOutput(context, c.Triples.First().Object, TripleSegment.Object, indent + 2 + addIndent)); c.Triples.RemoveAt(0); if (c.Triples.Count > 0) { output.AppendLine(" ; "); output.Append(' '); } } output.Append(']'); } } return output.ToString(); }
/// <summary> /// Saves a Graph to the given Stream using Turtle Syntax /// </summary> /// <param name="g">Graph to save</param> /// <param name="output">Stream to save to</param> public void Save(IGraph g, TextWriter output) { try { //Create the Writing Context g.NamespaceMap.Import(this._defaultNamespaces); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, output, this._compressionLevel, this._prettyprint, this._allowHiSpeed, this._syntax); this.GenerateOutput(context); } finally { try { output.Close(); } catch { //No Catch actions - just trying to clean up } } }
public void WritingCollectionCompressionSimple1() { Graph g = new Graph(); g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/")); INode n = g.CreateBlankNode(); INode rdfType = g.CreateUriNode("rdf:type"); g.Assert(g.CreateUriNode("ex:subj"), g.CreateUriNode("ex:pred"), n); g.Assert(n, rdfType, g.CreateUriNode("ex:BlankNode")); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Assert.AreEqual(1, context.Collections.Count, "Expected 1 Collection to be found"); Assert.AreEqual(1, context.Collections.First().Value.Triples.Count, "Expected 1 Triple to be in the collection"); this.CheckCompressionRoundTrip(g); }
public void WritingCollectionCompressionCyclic3() { Graph g = new Graph(); g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/")); g.NamespaceMap.AddNamespace("dnr", new Uri(ConfigurationLoader.ConfigurationNamespace)); INode a = g.CreateBlankNode(); INode b = g.CreateBlankNode(); INode c = g.CreateBlankNode(); INode d = g.CreateBlankNode(); INode e = g.CreateBlankNode(); INode pred = g.CreateUriNode("ex:pred"); g.Assert(d, pred, a); g.Assert(d, pred, g.CreateLiteralNode("D")); g.Assert(a, pred, b); g.Assert(a, pred, g.CreateLiteralNode("A")); g.Assert(b, pred, c); g.Assert(b, pred, g.CreateLiteralNode("B")); g.Assert(c, pred, a); g.Assert(c, pred, g.CreateLiteralNode("C")); g.Assert(e, pred, g.CreateLiteralNode("E")); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Assert.AreEqual(3, context.Collections.Count, "Expected 3 collections (one should be eliminated to break the cycle)"); this.CheckCompressionRoundTrip(g); }
public void WritingCollectionCompressionNamedListNodes2() { Graph g = new Graph(); g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/")); INode n = g.CreateUriNode("ex:listRoot"); INode m = g.CreateUriNode("ex:listItem"); INode rdfType = g.CreateUriNode("rdf:type"); INode rdfFirst = g.CreateUriNode("rdf:first"); INode rdfRest = g.CreateUriNode("rdf:rest"); INode rdfNil = g.CreateUriNode("rdf:nil"); g.Assert(g.CreateUriNode("ex:subj"), g.CreateUriNode("ex:pred"), n); g.Assert(n, rdfFirst, g.CreateLiteralNode("first")); g.Assert(n, rdfRest, m); g.Assert(m, rdfFirst, g.CreateLiteralNode("second")); g.Assert(m, rdfRest, rdfNil); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Assert.AreEqual(0, context.Collections.Count, "Expected no collections to be found"); this.CheckCompressionRoundTrip(g); }
public void WritingCollectionCompressionNamedListNodes3() { Graph g = new Graph(); INode data1 = g.CreateBlankNode(); g.Assert(data1, g.CreateUriNode(new Uri("http://property")), g.CreateLiteralNode("test1")); INode data2 = g.CreateBlankNode(); g.Assert(data2, g.CreateUriNode(new Uri("http://property")), g.CreateLiteralNode("test2")); INode listEntry1 = g.CreateUriNode(new Uri("http://test/1")); INode rdfFirst = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfListFirst)); INode rdfRest = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfListRest)); INode rdfNil = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfListNil)); g.Assert(listEntry1, rdfFirst, data1); g.Assert(listEntry1, rdfRest, rdfNil); INode listEntry2 = g.CreateUriNode(new Uri("http://test/2")); g.Assert(listEntry2, rdfFirst, data2); g.Assert(listEntry2, rdfRest, listEntry1); INode root = g.CreateUriNode(new Uri("http://root")); g.Assert(root, g.CreateUriNode(new Uri("http://list")), listEntry2); NTriplesFormatter formatter = new NTriplesFormatter(); Console.WriteLine("Original Graph"); foreach (Triple t in g.Triples) { Console.WriteLine(t.ToString(formatter)); } Console.WriteLine(); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Console.WriteLine(context.Collections.Count + " Collections Found"); Console.WriteLine(); System.IO.StringWriter strWriter = new System.IO.StringWriter(); CompressingTurtleWriter writer = new CompressingTurtleWriter(); writer.CompressionLevel = WriterCompressionLevel.High; writer.Save(g, strWriter); Console.WriteLine("Compressed Turtle"); Console.WriteLine(strWriter.ToString()); Console.WriteLine(); Graph h = new Graph(); TurtleParser parser = new TurtleParser(); StringParser.Parse(h, strWriter.ToString()); Console.WriteLine("Graph after Round Trip to Compressed Turtle"); foreach (Triple t in h.Triples) { Console.WriteLine(t.ToString(formatter)); } Assert.AreEqual(g, h, "Graphs should be equal"); }
public void WritingCollectionCompressionComplex2() { Graph g = new Graph(); g.LoadFromFile("complex-collections.nt"); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); NTriplesFormatter formatter = new NTriplesFormatter(); foreach (KeyValuePair<INode, OutputRdfCollection> kvp in context.Collections) { Console.WriteLine("Collection Root - " + kvp.Key.ToString(formatter)); Console.WriteLine("Collection Triples (" + kvp.Value.Triples.Count + ")"); foreach (Triple t in kvp.Value.Triples) { Console.WriteLine(t.ToString(formatter)); } Console.WriteLine(); } this.CheckCompressionRoundTrip(g); }
public void WritingCollectionCompressionComplex1() { SparqlConnector connector = new SparqlConnector(new VDS.RDF.Query.SparqlRemoteEndpoint(new Uri("http://dbpedia.org/sparql"))); Graph g = new Graph(); g.NamespaceMap.AddNamespace("ex", new Uri("http://example.org/")); g.NamespaceMap.AddNamespace("dnr", new Uri(ConfigurationLoader.ConfigurationNamespace)); INode n = g.CreateBlankNode(); g.Assert(g.CreateUriNode("ex:subj"), g.CreateUriNode("dnr:genericManager"), n); ConfigurationSerializationContext sContext = new ConfigurationSerializationContext(g); sContext.NextSubject = n; connector.SerializeConfiguration(sContext); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, Console.Out); WriterHelper.FindCollections(context); Assert.AreEqual(2, context.Collections.Count, "Expected 2 collections"); this.CheckCompressionRoundTrip(g); }
private bool GenerateVariableQuantificationOutput(CompressingTurtleWriterContext context, VariableContext varContext) { if (varContext.Type == VariableContextType.None) { return false; } else if (varContext.Type == VariableContextType.Existential) { context.Output.Write("@forSome "); } else { context.Output.Write("@forAll "); } foreach (INode var in varContext.Variables) { context.Output.Write(context.NodeFormatter.Format(var)); context.Output.Write(' '); } context.Output.WriteLine('.'); if (varContext.InnerContext != null) { this.GenerateVariableQuantificationOutput(context, varContext.InnerContext); } return true; }
/// <summary> /// Generates Output for Nodes in Notation 3 syntax /// </summary> /// <param name="context">Writer Context</param> /// <param name="n">Node to generate output for</param> /// <param name="segment">Segment of the Triple being output</param> /// <param name="indent">Indent to use for pretty printing</param> /// <returns></returns> private String GenerateNodeOutput(CompressingTurtleWriterContext context, INode n, TripleSegment segment, int indent) { StringBuilder output = new StringBuilder(); switch (n.NodeType) { case NodeType.Blank: if (context.Collections.ContainsKey(n)) { output.Append(this.GenerateCollectionOutput(context, context.Collections[n], indent)); } else { return context.NodeFormatter.Format(n, segment); } break; case NodeType.GraphLiteral: if (segment == TripleSegment.Predicate) throw new RdfOutputException(WriterErrorMessages.GraphLiteralPredicatesUnserializable("Notation 3")); output.Append("{"); IGraphLiteralNode glit = (IGraphLiteralNode)n; StringBuilder temp = new StringBuilder(); CompressingTurtleWriterContext subcontext = new CompressingTurtleWriterContext(glit.SubGraph, new System.IO.StringWriter(temp)); subcontext.NodeFormatter = context.NodeFormatter; bool contextWritten = false; //Write Triples 1 at a Time on a single line foreach (Triple t in subcontext.Graph.Triples) { if (!contextWritten && t.Context != null && t.Context is VariableContext) { contextWritten = this.GenerateVariableQuantificationOutput(subcontext, (VariableContext)t.Context); if (contextWritten) output.Append(temp.ToString()); } output.Append(this.GenerateNodeOutput(subcontext, t.Subject, TripleSegment.Subject, 0)); output.Append(" "); output.Append(this.GenerateNodeOutput(subcontext, t.Predicate, TripleSegment.Predicate, 0)); output.Append(" "); output.Append(this.GenerateNodeOutput(subcontext, t.Object, TripleSegment.Object, 0)); output.Append(". "); } output.Append("}"); break; case NodeType.Literal: if (segment == TripleSegment.Predicate) throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("Notation 3")); return context.NodeFormatter.Format(n, segment); case NodeType.Uri: return context.NodeFormatter.Format(n, segment); case NodeType.Variable: return context.NodeFormatter.Format(n, segment); default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("Notation 3")); } return output.ToString(); }
/// <summary> /// Saves a Graph to the given Stream using Notation 3 Syntax /// </summary> /// <param name="g">Graph to save</param> /// <param name="output">Stream to save to</param> public void Save(IGraph g, TextWriter output) { try { g.NamespaceMap.Import(this._defaultNamespaces); CompressingTurtleWriterContext context = new CompressingTurtleWriterContext(g, output, this._compressionLevel, this._prettyprint, this._allowHiSpeed); context.NodeFormatter = new Notation3Formatter(g); this.GenerateOutput(context); } finally { try { output.Close(); } catch { //No Catch actions - just trying to clean up } } }