private IToken TryGetNumericLiteral() { bool dotoccurred = false; bool expoccurred = false; bool signoccurred = false; if (this.Length == 1) { dotoccurred = true; } char next = this.Peek(); //Read the Characters of the Numeric Literal while (Char.IsDigit(next) || next == '-' || next == '+' || (next == '.' && !dotoccurred) || next == 'e' || next == 'E') { if (next == '-' || next == '+') { //Sign can occur at start and immediatedly after an exponent if ((signoccurred || expoccurred) && !(this.Value.EndsWith("e") || this.Value.EndsWith("E"))) { //+/- can only occur once at start and once after exponent throw Error("Unexpected Character " + next + " encountered while parsing a Numeric Literal from input '" + this.Value + "', a +/- to specify sign has already occurred in this Numeric Literal"); } signoccurred = true; } else if (next == '.') { dotoccurred = true; } else if (next == 'e' || next == 'E') { if (expoccurred) { throw Error("Unexpected Character " + next + " encountered while parsing a Numeric Literal from input '" + this.Value + "', a e/E to specify exponent has already occurred in this Numeric Literal"); } expoccurred = true; } this.ConsumeCharacter(); next = this.Peek(); } if (this.Value.EndsWith(".")) { this.Backtrack(); } //Validate if (TurtleSpecsHelper.IsValidPlainLiteral(this.Value, TurtleSyntax.Original)) { this._lasttokentype = Token.PLAINLITERAL; return(new PlainLiteralToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); } else { throw Error("The input '" + this.Value + "' is not a valid Plain Literal in {0}"); } }
private IToken TryGetPlainLiteralOrQName() { //Read Valid Plain Literal and QName Chars char next = this.Peek(); bool colonoccurred = false; while (Char.IsLetterOrDigit(next) || next == '_' || next == '-' || next == ':') { this.ConsumeCharacter(); if (next == ':') { if (colonoccurred) { throw Error("Unexpected Colon encountered in input '" + this.Value + "', a Colon may only occur once in a QName"); } colonoccurred = true; } next = this.Peek(); } //Validate String value = this.Value; //If it ends in a trailing . then we need to backtrack if (value.EndsWith(".")) { this.Backtrack(); value = value.Substring(0, value.Length - 1); } if (value.Equals("a")) { //Keyword 'a' this._lasttokentype = Token.KEYWORDA; return(new KeywordAToken(this.CurrentLine, this.StartPosition)); } else if (value.Equals("true") || value.Equals("false")) { //Boolean Plain Literal this._lasttokentype = Token.PLAINLITERAL; return(new PlainLiteralToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); } else if (TurtleSpecsHelper.IsValidQName(value)) { //QName this._lasttokentype = Token.QNAME; return(new QNameToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); } else { //Error throw Error("Unexpected input '" + value + "', expected a QName, the 'a' Keyword or a Plain Literal"); } }
private IToken TryGetQName() { bool colonoccurred = false; char next = this.Peek(); while (Char.IsLetterOrDigit(next) || next == '-' || next == '_' || next == ':') { this.ConsumeCharacter(); if (next == ':') { if (colonoccurred) { throw Error("Unexpected Colon encountered in input '" + this.Value + "', a Colon may only occur once in a QName"); } colonoccurred = true; } next = this.Peek(); } if (this.Value.StartsWith(".")) { this.Backtrack(); } //Validate the QName if (this.Value.StartsWith("_:")) { //Blank Node ID this._lasttokentype = Token.BLANKNODEWITHID; return(new BlankNodeWithIDToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); } else if (TurtleSpecsHelper.IsValidQName(this.Value)) { //QName this._lasttokentype = Token.QNAME; return(new QNameToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); } else { throw Error("The input '" + this.Value + "' is not a valid QName in {0}"); } }
private IToken TryGetPlainLiteral() { this.ConsumeCharacter(); char next = this.Peek(); while (Char.IsLetter(next)) { this.ConsumeCharacter(); next = this.Peek(); } if (TurtleSpecsHelper.IsValidPlainLiteral(this.Value)) { this.LastTokenType = Token.PLAINLITERAL; return(new PlainLiteralToken(this.Value, this.StartLine, this.StartPosition, this.EndPosition)); } else { throw new RdfParseException("'" + this.Value + "' is not a valid Plain Literal!"); } }
private IToken TryGetPlainLiteral() { ConsumeCharacter(); char next = Peek(); while (Char.IsLetter(next)) { ConsumeCharacter(); next = Peek(); } if (TurtleSpecsHelper.IsValidPlainLiteral(Value, TurtleSyntax.Original)) { LastTokenType = Token.PLAINLITERAL; return(new PlainLiteralToken(Value, StartLine, StartPosition, EndPosition)); } else { throw new RdfParseException("'" + Value + "' is not a valid Plain Literal!"); } }
/// <summary> /// Generates the Output for a Graph as a String in TriG syntax /// </summary> /// <param name="globalContext">Context for writing the Store</param> /// <param name="context">Context for writing the Graph</param> /// <returns></returns> private String GenerateGraphOutput(TriGWriterContext globalContext, TurtleWriterContext context) { if (!WriterHelper.IsDefaultGraph(context.Graph.BaseUri)) { //Named Graph String gname; String sep = (globalContext.N3CompatabilityMode) ? " = " : " "; if (globalContext.CompressionLevel > WriterCompressionLevel.None && globalContext.QNameMapper.ReduceToQName(context.Graph.BaseUri.ToString(), out gname)) { if (TurtleSpecsHelper.IsValidQName(gname)) { context.Output.WriteLine(gname + sep + "{"); } else { context.Output.WriteLine("<" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">" + sep + "{"); } } else { context.Output.WriteLine("<" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">" + sep + "{"); } } else { context.Output.WriteLine("{"); } //Generate Triples this.GenerateTripleOutput(globalContext, context); //Close the Graph context.Output.WriteLine("}"); return(context.Output.ToString()); }
private IToken TryGetPrefix() { //Get the prefix char next = this.Peek(); while (!Char.IsWhiteSpace(next)) { this.ConsumeCharacter(); next = this.Peek(); } //Last character must be a : if (!this.Value.EndsWith(":")) { throw this.UnexpectedCharacter(next, "expected a : to end a Prefix specification"); } if (!TurtleSpecsHelper.IsValidQName(this.Value)) { throw new RdfParseException("The value '" + this.Value + "' is not a valid Prefix in TriG", new PositionInfo(this.StartLine, this.CurrentLine, this.StartPosition, this.EndPosition)); } this._lasttokentype = Token.PREFIX; return(new PrefixToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition)); }
private IToken TryGetPrefix() { // Get the prefix char next = Peek(); while (!Char.IsWhiteSpace(next)) { ConsumeCharacter(); next = Peek(); } // Last character must be a : if (!Value.EndsWith(":")) { throw UnexpectedCharacter(next, "expected a : to end a Prefix specification"); } if (!TurtleSpecsHelper.IsValidQName(Value, _syntax == TriGSyntax.Recommendation ? TurtleSyntax.W3C : TurtleSyntax.Original)) { throw new RdfParseException("The value '" + Value + "' is not a valid Prefix in TriG", new PositionInfo(StartLine, CurrentLine, StartPosition, EndPosition)); } _lasttokentype = Token.PREFIX; return(new PrefixToken(Value, CurrentLine, StartPosition, EndPosition)); }
/// <summary> /// Gets whether a QName is valid in Turtle as specified by the W3C. /// </summary> /// <param name="value">QName.</param> /// <returns></returns> protected override bool IsValidQName(string value) { return(TurtleSpecsHelper.IsValidQName(value, TurtleSyntax.W3C)); }
/// <summary> /// Formats a Literal Node as a String /// </summary> /// <param name="l">Literal Node</param> /// <param name="segment">Triple Segment</param> /// <returns></returns> protected override string FormatLiteralNode(ILiteralNode l, TripleSegment?segment) { StringBuilder output = new StringBuilder(); String value, qname; bool longlit = false, plainlit = false; longlit = TurtleSpecsHelper.IsLongLiteral(l.Value); plainlit = TurtleSpecsHelper.IsValidPlainLiteral(l.Value, l.DataType); if (plainlit) { if (TurtleSpecsHelper.IsValidDecimal(l.Value) && l.Value.EndsWith(".")) { //Ensure we strip the trailing dot of any xsd:decimal and add a datatype definition output.Append('"'); output.Append(l.Value.Substring(0, l.Value.Length - 1)); output.Append("\"^^<"); output.Append(this.FormatUri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)); output.Append('>'); } else { //Otherwise just write out the value output.Append(l.Value); } //For integers ensure we insert a space after the literal to ensure it can't ever be confused with a decimal if (TurtleSpecsHelper.IsValidInteger(l.Value)) { output.Append(' '); } } else { output.Append('"'); if (longlit) { output.Append("\"\""); } value = l.Value; bool fullyEscaped = (longlit) ? value.IsFullyEscaped(this._validEscapes, this._longLitMustEscape) : value.IsFullyEscaped(this._validEscapes, this._litMustEscape); if (!fullyEscaped) { //This first replace escapes all back slashes for good measure value = value.EscapeBackslashes(this._validEscapes); //Then remove null character since it doesn't change the meaning of the Literal value = value.Replace("\0", ""); //Don't need all the other escapes for long literals as the characters that would be escaped are permitted in long literals //Need to escape " still value = value.Escape('"'); if (!longlit) { //Then if we're not a long literal we'll escape tabs value = value.Replace("\t", "\\t"); } } output.Append(value); output.Append('"'); if (longlit) { output.Append("\"\""); } if (!l.Language.Equals(String.Empty)) { output.Append('@'); output.Append(l.Language.ToLower()); } else if (l.DataType != null) { output.Append("^^"); if (this._qnameMapper.ReduceToQName(l.DataType.ToString(), out qname)) { if (TurtleSpecsHelper.IsValidQName(qname)) { output.Append(qname); } else { output.Append('<'); output.Append(this.FormatUri(l.DataType)); output.Append('>'); } } else { output.Append('<'); output.Append(this.FormatUri(l.DataType)); output.Append('>'); } } } return(output.ToString()); }
/// <summary> /// Saves a Store in TriG (Turtle with Named Graphs) format. /// </summary> /// <param name="store">Store to save.</param> /// <param name="writer">Writer to save to.</param> /// <param name="leaveOpen">Boolean flag indicating if <paramref name="writer"/> should be left open after the store is saved.</param> public void Save(ITripleStore store, TextWriter writer, bool leaveOpen) { if (store == null) { throw new RdfOutputException("Cannot output a null Triple Store"); } if (writer == null) { throw new RdfOutputException("Cannot output to a null writer"); } TriGWriterContext context = new TriGWriterContext(store, writer, _prettyprint, _allowHiSpeed, _compressionLevel, _n3compat); // Check there's something to do if (context.Store.Graphs.Count == 0) { if (!leaveOpen) { context.Output.Close(); } return; } // Write the Header of the File foreach (var g in context.Store.Graphs) { context.NamespaceMap.Import(g.NamespaceMap); } if (context.CompressionLevel > WriterCompressionLevel.None) { // Only add @prefix declarations if compression is enabled context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap); foreach (string prefix in context.NamespaceMap.Prefixes) { if (TurtleSpecsHelper.IsValidQName(prefix + ":")) { context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">."); } } context.Output.WriteLine(); } else { context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true)); } if (_useMultiThreading) { // Standard Multi-Threaded Writing // Queue the Graphs to be written foreach (IGraph g in context.Store.Graphs) { context.Add(g.BaseUri); } // Start making the async calls var workers = new Task[_threads]; for (int i = 0; i < _threads; i++) { workers[i] = Task.Factory.StartNew(() => SaveGraphs(context)); } try { Task.WaitAll(workers); } catch (AggregateException ex) { var outputException = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG")); foreach (var innerException in ex.InnerExceptions) { outputException.AddException(innerException); } } finally { // Make sure to close the output if (!leaveOpen) { context.Output.Close(); } } } else { try { // Optional Single Threaded Writing foreach (IGraph g in store.Graphs) { TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted); if (context.CompressionLevel > WriterCompressionLevel.None) { graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper); } else { graphContext.NodeFormatter = new UncompressedTurtleFormatter(); } context.Output.WriteLine(GenerateGraphOutput(context, graphContext)); } // Make sure to close the output if (!leaveOpen) { context.Output.Close(); } } catch { try { // Close the output if (!leaveOpen) { context.Output.Close(); } } catch { // No catch actions, just cleaning up the output stream } throw; } } }
/// <summary> /// Generates the Output for a Graph /// </summary> /// <param name="context">Context for writing the Graph</param> private void GenerateOutput(TurtleWriterContext context) { //Write Base Uri if (context.Graph.BaseUri != null) { context.Output.WriteLine("@base <" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">."); context.Output.WriteLine(); } //Write Prefixes foreach (String prefix in context.Graph.NamespaceMap.Prefixes) { if (TurtleSpecsHelper.IsValidQName(prefix + ":")) { context.Output.Write("@prefix " + prefix + ": <"); String nsUri = context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(prefix)); context.Output.WriteLine(nsUri + ">."); } } context.Output.WriteLine(); //Decide which 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 (hiSpeed && context.HighSpeedModePermitted) { //High Speed Writing Mode //Writes everything as individual Triples this.RaiseWarning("High Speed Write Mode in use - minimal syntax compressions will be used"); context.NodeFormatter = new UncompressedTurtleFormatter(); foreach (Triple t in context.Graph.Triples) { context.Output.Write(this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject)); context.Output.Write(" "); context.Output.Write(this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate)); context.Output.Write(" "); context.Output.Write(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object)); context.Output.WriteLine("."); } } else { //Get the Triples as a Sorted List List <Triple> ts = context.Graph.Triples.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); context.Output.Write(temp); context.Output.Write(" "); subjIndent = temp.Length + 1; lastSubj = t.Subject; //Write the first Predicate temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); 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); 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)); } //Terminate Triples if (ts.Count > 0) { context.Output.WriteLine("."); } } }
/// <summary> /// Saves a Store in TriG (Turtle with Named Graphs) format /// </summary> /// <param name="store">Store to save</param> /// <param name="parameters">Parameters indicating a Stream to write to</param> public void Save(ITripleStore store, IStoreParams parameters) { //Try and determine the TextWriter to output to TriGWriterContext context = null; if (parameters is StreamParams) { //Create a new Writer Context ((StreamParams)parameters).Encoding = new UTF8Encoding(Options.UseBomForUtf8); context = new TriGWriterContext(store, ((StreamParams)parameters).StreamWriter, this._prettyprint, this._allowHiSpeed, this._compressionLevel, this._n3compat); } else if (parameters is TextWriterParams) { context = new TriGWriterContext(store, ((TextWriterParams)parameters).TextWriter, this._prettyprint, this._allowHiSpeed, this._compressionLevel, this._n3compat); } if (context != null) { //Check there's something to do if (context.Store.Graphs.Count == 0) { context.Output.Close(); return; } //Write the Header of the File foreach (IGraph g in context.Store.Graphs) { context.NamespaceMap.Import(g.NamespaceMap); } if (context.CompressionLevel > WriterCompressionLevel.None) { //Only add @prefix declarations if compression is enabled context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap); foreach (String prefix in context.NamespaceMap.Prefixes) { if (TurtleSpecsHelper.IsValidQName(prefix + ":")) { context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">."); } } context.Output.WriteLine(); } else { context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true)); } if (this._useMultiThreading) { //Standard Multi-Threaded Writing //Queue the Graphs to be written foreach (IGraph g in context.Store.Graphs) { if (g.BaseUri == null) { context.Add(new Uri(GraphCollection.DefaultGraphUri)); } else { context.Add(g.BaseUri); } } //Start making the async calls List <IAsyncResult> results = new List <IAsyncResult>(); SaveGraphsDelegate d = new SaveGraphsDelegate(this.SaveGraphs); for (int i = 0; i < this._threads; i++) { results.Add(d.BeginInvoke(context, null, null)); } //Wait for all the async calls to complete WaitHandle.WaitAll(results.Select(r => r.AsyncWaitHandle).ToArray()); RdfThreadedOutputException outputEx = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG")); foreach (IAsyncResult result in results) { try { d.EndInvoke(result); } catch (Exception ex) { outputEx.AddException(ex); } } //Make sure to close the output context.Output.Close(); //If there were any errors we'll throw an RdfThreadedOutputException now if (outputEx.InnerExceptions.Any()) { throw outputEx; } } else { try { //Optional Single Threaded Writing foreach (IGraph g in store.Graphs) { TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted); if (context.CompressionLevel > WriterCompressionLevel.None) { graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper); } else { graphContext.NodeFormatter = new UncompressedTurtleFormatter(); } context.Output.WriteLine(this.GenerateGraphOutput(context, graphContext)); } //Make sure to close the output context.Output.Close(); } catch { try { //Close the output context.Output.Close(); } catch { //No catch actions, just cleaning up the output stream } throw; } } } else { throw new RdfStorageException("Parameters for the TriGWriter must be of the type StreamParams/TextWriterParams"); } }
/// <summary> /// Internal method which generates the HTML Output for the Graph /// </summary> /// <param name="context">Writer Context</param> private void GenerateOutput(HtmlWriterContext context) { Object results; // Add the Namespaces we want to use later on context.QNameMapper.AddNamespace("owl", UriFactory.Create(NamespaceMapper.OWL)); context.QNameMapper.AddNamespace("rdf", UriFactory.Create(NamespaceMapper.RDF)); context.QNameMapper.AddNamespace("rdfs", UriFactory.Create(NamespaceMapper.RDFS)); context.QNameMapper.AddNamespace("dc", UriFactory.Create("http://purl.org/dc/elements/1.1/")); context.QNameMapper.AddNamespace("dct", UriFactory.Create("http://purl.org/dc/terms/")); context.QNameMapper.AddNamespace("vann", UriFactory.Create("http://purl.org/vocab/vann/")); context.QNameMapper.AddNamespace("vs", UriFactory.Create("http://www.w3.org/2003/06/sw-vocab-status/ns#")); // Find the Node that represents the Schema Ontology // Assumes there is exactly one thing given rdf:type owl:Ontology IUriNode ontology = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "Ontology")); IUriNode rdfType = context.Graph.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType)); IUriNode rdfsLabel = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "label")); INode ontoNode = context.Graph.GetTriplesWithPredicateObject(rdfType, ontology).Select(t => t.Subject).FirstOrDefault(); INode ontoLabel = (ontoNode != null) ? context.Graph.GetTriplesWithSubjectPredicate(ontoNode, rdfsLabel).Select(t => t.Object).FirstOrDefault() : null; // Stuff for formatting // We'll use the Turtle Formatter to get nice QNames wherever possible context.NodeFormatter = new TurtleFormatter(context.QNameMapper); context.UriFormatter = (IUriFormatter)context.NodeFormatter; // Page Header context.HtmlWriter.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML+RDFa 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd\">"); context.HtmlWriter.WriteLine(); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Html); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Head); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Title); context.HtmlWriter.WriteEncodedText("Schema"); if (ontoNode != null && ontoLabel != null) { context.HtmlWriter.WriteEncodedText(" - " + ontoLabel.ToSafeString()); } else if (context.Graph.BaseUri != null) { context.HtmlWriter.WriteEncodedText(" - " + context.Graph.BaseUri.AbsoluteUri); } context.HtmlWriter.RenderEndTag(); if (!this.Stylesheet.Equals(String.Empty)) { context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Href, this.Stylesheet); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Type, "text/css"); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet"); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Link); context.HtmlWriter.RenderEndTag(); } context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Start Body context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Body); // Title context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H2); context.HtmlWriter.WriteEncodedText("Schema"); if (ontoNode != null && ontoLabel != null) { context.HtmlWriter.WriteEncodedText(" - " + ontoLabel.ToSafeString()); } else if (context.Graph.BaseUri != null) { context.HtmlWriter.WriteEncodedText(" - " + context.Graph.BaseUri.AbsoluteUri); } context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Show the Description of the Schema (if any) if (ontoNode != null) { SparqlParameterizedString getOntoDescrip = new SparqlParameterizedString(); getOntoDescrip.Namespaces = context.QNameMapper; getOntoDescrip.CommandText = "SELECT * WHERE { @onto a owl:Ontology . OPTIONAL { @onto rdfs:comment ?description } . OPTIONAL { @onto vann:preferredNamespacePrefix ?nsPrefix ; vann:preferredNamespaceUri ?nsUri } . OPTIONAL { @onto dc:creator ?creator . ?creator (foaf:name | rdfs:label) ?creatorName } }"; getOntoDescrip.SetParameter("onto", ontoNode); try { results = context.Graph.ExecuteQuery(getOntoDescrip); if (results is SparqlResultSet) { if (!((SparqlResultSet)results).IsEmpty) { SparqlResult ontoInfo = ((SparqlResultSet)results)[0]; // Show rdfs:comment on the Ontology if (ontoInfo.HasValue("description")) { INode descrip = ontoInfo["description"]; if (descrip.NodeType == NodeType.Literal) { context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.Write(((ILiteralNode)descrip).Value); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); } } // Show Author Information if (ontoInfo.HasValue("creator")) { INode author = ontoInfo["creator"]; INode authorName = ontoInfo["creatorName"]; context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em); context.HtmlWriter.WriteEncodedText("Schema created by "); if (author.NodeType == NodeType.Uri) { context.HtmlWriter.AddAttribute("href", ((IUriNode)author).Uri.AbsoluteUri); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); } switch (authorName.NodeType) { case NodeType.Uri: context.HtmlWriter.WriteEncodedText(((IUriNode)authorName).Uri.AbsoluteUri); break; case NodeType.Literal: context.HtmlWriter.WriteEncodedText(((ILiteralNode)authorName).Value); break; default: context.HtmlWriter.WriteEncodedText(authorName.ToString()); break; } if (author.NodeType == NodeType.Uri) { context.HtmlWriter.RenderEndTag(); } context.HtmlWriter.RenderEndTag(); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); } // Show the Namespace information for the Schema if (ontoInfo.HasValue("nsPrefix")) { if (ontoInfo["nsPrefix"].NodeType == NodeType.Literal && ontoInfo["nsUri"].NodeType == NodeType.Uri) { // Add this QName to the QName Mapper so we can get nice QNames later on String prefix = ((ILiteralNode)ontoInfo["nsPrefix"]).Value; context.QNameMapper.AddNamespace(prefix, ((IUriNode)ontoInfo["nsUri"]).Uri); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4); context.HtmlWriter.WriteEncodedText("Preferred Namespace Definition"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Show human readable description of preferred Namespace Settings context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.WriteEncodedText("Preferred Namespace Prefix is "); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Strong); context.HtmlWriter.WriteEncodedText(prefix); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteEncodedText(" and preferred Namespace URI is "); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Href, context.QNameMapper.GetNamespaceUri(prefix).AbsoluteUri); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); context.HtmlWriter.WriteEncodedText(context.QNameMapper.GetNamespaceUri(prefix).AbsoluteUri); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.RenderEndTag(); // RDF/XML Syntax context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5); context.HtmlWriter.WriteEncodedText("RDF/XML Syntax"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%"); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre); int currIndent = context.HtmlWriter.Indent; context.HtmlWriter.Indent = 0; context.HtmlWriter.WriteEncodedText("<?xml version=\"1.0\" charset=\"utf-8\"?>"); context.HtmlWriter.WriteLine(); context.HtmlWriter.WriteEncodedText("<rdf:RDF xmlns:rdf=\"" + NamespaceMapper.RDF + "\" xmlns:" + prefix + "=\"" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + "\">"); context.HtmlWriter.WriteLine(); context.HtmlWriter.WriteEncodedText(" <!-- Your RDF here... -->"); context.HtmlWriter.WriteLine(); context.HtmlWriter.WriteEncodedText("</rdf:RDF>"); context.HtmlWriter.Indent = currIndent; context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Turtle/N3 Syntax context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5); context.HtmlWriter.WriteEncodedText("Turtle/N3 Syntax"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%"); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre); currIndent = context.HtmlWriter.Indent; context.HtmlWriter.Indent = 0; context.HtmlWriter.WriteEncodedText("@prefix " + prefix + ": <" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + "> ."); context.HtmlWriter.Indent = currIndent; context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // SPARQL Syntax context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5); context.HtmlWriter.WriteEncodedText("SPARQL Syntax"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%"); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre); currIndent = context.HtmlWriter.Indent; context.HtmlWriter.Indent = 0; context.HtmlWriter.WriteEncodedText("PREFIX " + prefix + ": <" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + ">"); context.HtmlWriter.Indent = currIndent; context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); } } } } else { throw new RdfOutputException("Tried to make a SPARQL Query to determine Schema Information but an unexpected Query Result was returned"); } } catch (RdfQueryException queryEx) { throw new RdfOutputException("Tried to make a SPARQL Query to determine Schema Information but a Query Error occurred", queryEx); } } SparqlParameterizedString getPropertyRanges = new SparqlParameterizedString(); getPropertyRanges.Namespaces = new NamespaceMapper(); getPropertyRanges.Namespaces.AddNamespace("owl", UriFactory.Create(NamespaceMapper.OWL)); getPropertyRanges.CommandText = "SELECT ?range WHERE { { @property rdfs:range ?range . FILTER(ISURI(?range)) } UNION { @property rdfs:range ?union . ?union owl:unionOf ?ranges . { ?ranges rdf:first ?range } UNION { ?ranges rdf:rest+/rdf:first ?range } } }"; SparqlParameterizedString getPropertyDomains = new SparqlParameterizedString(); getPropertyDomains.Namespaces = getPropertyRanges.Namespaces; getPropertyDomains.CommandText = "SELECT ?domain WHERE { { @property rdfs:domain ?domain . FILTER(ISURI(?domain)) } UNION { @property rdfs:domain ?union . ?union owl:unionOf ?domains . { ?domains rdf:first ?domain } UNION { ?domains rdf:rest+/rdf:first ?domain } } }"; // Show lists of all Classes and Properties in the Schema context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4); context.HtmlWriter.WriteEncodedText("Class and Property Summary"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.WriteEncodedText("This Schema defines the following classes:"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.AddStyleAttribute("width", "90%"); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); // Get the Classes and Display SparqlParameterizedString getClasses = new SparqlParameterizedString(); getClasses.Namespaces = context.QNameMapper; getClasses.CommandText = "SELECT DISTINCT ?class WHERE { { ?class a rdfs:Class } UNION { ?class a owl:Class } FILTER(ISURI(?class)) } ORDER BY ?class"; try { results = context.Graph.ExecuteQuery(getClasses); if (results is SparqlResultSet) { SparqlResultSet rs = (SparqlResultSet)results; for (int i = 0; i < rs.Count; i++) { SparqlResult r = rs[i]; // Get the QName and output a Link to an anchor that we'll generate later to let // users jump to a Class/Property definition String qname = context.NodeFormatter.Format(r["class"]); context.HtmlWriter.AddAttribute("href", "#" + qname); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); context.HtmlWriter.WriteEncodedText(qname); context.HtmlWriter.RenderEndTag(); if (i < rs.Count - 1) { context.HtmlWriter.WriteEncodedText(" , "); } } } else { throw new RdfOutputException("Tried to make a SPARQL Query to find Classes in the Schema but an unexpected Query Result was returned"); } } catch (RdfQueryException queryEx) { throw new RdfOutputException("Tried to make a SPARQL Query to find Classes in the Schema but a Query Error occurred", queryEx); } context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.WriteEncodedText("This Schema defines the following properties:"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); context.HtmlWriter.AddStyleAttribute("width", "90%"); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); // Get the Properties and Display SparqlParameterizedString getProperties = new SparqlParameterizedString(); getProperties.Namespaces = context.QNameMapper; getProperties.CommandText = "SELECT DISTINCT ?property WHERE { { ?property a rdf:Property } UNION { ?property a owl:DatatypeProperty } UNION { ?property a owl:ObjectProperty } FILTER(ISURI(?property)) } ORDER BY ?property"; try { results = context.Graph.ExecuteQuery(getProperties); if (results is SparqlResultSet) { SparqlResultSet rs = (SparqlResultSet)results; for (int i = 0; i < rs.Count; i++) { SparqlResult r = rs[i]; // Get the QName and output a Link to an anchor that we'll generate later to let // users jump to a Class/Property definition String qname = context.NodeFormatter.Format(r["property"]); context.HtmlWriter.AddAttribute("href", "#" + qname); context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); context.HtmlWriter.WriteEncodedText(qname); context.HtmlWriter.RenderEndTag(); if (i < rs.Count - 1) { context.HtmlWriter.WriteEncodedText(" , "); } } } else { throw new RdfOutputException("Tried to make a SPARQL Query to find Properties in the Schema but an unexpected Query Result was returned"); } } catch (RdfQueryException queryEx) { throw new RdfOutputException("Tried to make a SPARQL Query to find Properties in the Schema but a Query Error occurred", queryEx); } context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Show details for each class context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H3); context.HtmlWriter.WriteEncodedText("Classes"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Now create the URI Nodes we need for the next stage of Output IUriNode rdfsDomain = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "domain")); IUriNode rdfsRange = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "range")); IUriNode rdfsSubClassOf = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "subClassOf")); IUriNode rdfsSubPropertyOf = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "subPropertyOf")); IUriNode owlDisjointClass = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "disjointWith")); IUriNode owlEquivalentClass = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "equivalentClass")); IUriNode owlEquivalentProperty = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "equivalentProperty")); IUriNode owlInverseProperty = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "inverseOf")); // Alter our previous getClasses query to get additional details getClasses.CommandText = "SELECT ?class (SAMPLE(?label) AS ?classLabel) (SAMPLE(?description) AS ?classDescription) WHERE { { ?class a rdfs:Class } UNION { ?class a owl:Class } FILTER(ISURI(?class)) OPTIONAL { ?class rdfs:label ?label } OPTIONAL { ?class rdfs:comment ?description } } GROUP BY ?class ORDER BY ?class"; try { results = context.Graph.ExecuteQuery(getClasses); if (results is SparqlResultSet) { foreach (SparqlResult r in (SparqlResultSet)results) { if (!r.HasValue("class")) { continue; } String qname = context.NodeFormatter.Format(r["class"]); // Use a <div> for each Class context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Div); // Add the Anchor to which earlier Class summary links to context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Name, qname); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); context.HtmlWriter.RenderEndTag(); // Show Basic Class Information context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4); context.HtmlWriter.WriteEncodedText("Class: " + qname); context.HtmlWriter.RenderEndTag(); // Show "Local Name - Label" context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em); if (TurtleSpecsHelper.IsValidQName(qname)) { context.HtmlWriter.WriteEncodedText(qname); } else { Uri temp = new Uri(qname, UriKind.RelativeOrAbsolute); if (!temp.Fragment.Equals(String.Empty)) { context.HtmlWriter.WriteEncodedText(temp.Fragment); } else { context.HtmlWriter.WriteEncodedText(temp.Segments.Last()); } } context.HtmlWriter.RenderEndTag(); if (r.HasValue("classLabel")) { if (r["classLabel"] != null && r["classLabel"].NodeType == NodeType.Literal) { context.HtmlWriter.WriteEncodedText(" - "); context.HtmlWriter.WriteEncodedText(((ILiteralNode)r["classLabel"]).Value); } } context.HtmlWriter.WriteLine(); context.HtmlWriter.WriteBreak(); context.HtmlWriter.WriteLine(); // Output further information about the class IEnumerable <Triple> ts; // Output any Subclasses ts = context.Graph.GetTriplesWithSubjectPredicate(rdfsSubClassOf, r["class"]); this.GenerateCaptionedInformation(context, "Has Sub Classes", ts, t => t.Object); // Output Properties which have this as domain/range ts = context.Graph.GetTriplesWithPredicateObject(rdfsDomain, r["class"]); this.GenerateCaptionedInformation(context, "Properties Include", ts, t => t.Subject); ts = context.Graph.GetTriplesWithPredicateObject(rdfsRange, r["class"]); this.GenerateCaptionedInformation(context, "Used With", ts, t => t.Subject); // Output any Equivalent Classes ts = context.Graph.GetTriplesWithSubjectPredicate(r["class"], owlEquivalentClass).Concat(context.Graph.GetTriplesWithPredicateObject(owlEquivalentClass, r["class"])); this.GenerateCaptionedInformation(context, "Equivalent Classes", ts, t => t.Subject.Equals(r["class"]) ? t.Object : t.Subject); // Output any Disjoint Classes ts = context.Graph.GetTriplesWithSubjectPredicate(r["class"], owlDisjointClass).Concat(context.Graph.GetTriplesWithPredicateObject(owlDisjointClass, r["class"])); this.GenerateCaptionedInformation(context, "Disjoint Classes", ts, t => t.Subject.Equals(r["class"]) ? t.Object : t.Subject); // Show the Class Description if (r.HasValue("classDescription")) { if (r["classDescription"] != null && r["classDescription"].NodeType == NodeType.Literal) { context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.Write(((ILiteralNode)r["classDescription"]).Value); context.HtmlWriter.RenderEndTag(); } } // End the </div> for the Class context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); } } else { throw new RdfOutputException("Tried to make a SPARQL Query to get Class Information from the Schema but an unexpected Query Result was returned"); } } catch (RdfQueryException queryEx) { throw new RdfOutputException("Tried to make a SPARQL Query to get Class Information from the Schema but a Query Error occurred", queryEx); } // Show details for each property context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H3); context.HtmlWriter.WriteEncodedText("Properties"); context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); // Alter our previous getProperties query to get additional details getProperties.CommandText = "SELECT ?property (SAMPLE(?label) AS ?propertyLabel) (SAMPLE(?description) AS ?propertyDescription) WHERE { { ?property a rdf:Property } UNION { ?property a owl:ObjectProperty } UNION { ?property a owl:DatatypeProperty } FILTER(ISURI(?property)) OPTIONAL { ?property rdfs:label ?label } OPTIONAL { ?property rdfs:comment ?description } } GROUP BY ?property ORDER BY ?property"; try { results = context.Graph.ExecuteQuery(getProperties); if (results is SparqlResultSet) { foreach (SparqlResult r in (SparqlResultSet)results) { if (!r.HasValue("property")) { continue; } String qname = context.NodeFormatter.Format(r["property"]); // Use a <div> for each Property context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Div); // Add the Anchor to which earlier Property summary links to context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Name, qname); context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A); context.HtmlWriter.RenderEndTag(); // Show Basic Property Information context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4); context.HtmlWriter.WriteEncodedText("Property: " + qname); context.HtmlWriter.RenderEndTag(); // Show "Local Name - Label" context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em); if (TurtleSpecsHelper.IsValidQName(qname)) { context.HtmlWriter.WriteEncodedText(qname); } else { Uri temp = new Uri(qname, UriKind.RelativeOrAbsolute); if (!temp.Fragment.Equals(String.Empty)) { context.HtmlWriter.WriteEncodedText(temp.Fragment); } else { context.HtmlWriter.WriteEncodedText(temp.Segments.Last()); } } context.HtmlWriter.RenderEndTag(); if (r.HasValue("propertyLabel")) { if (r["propertyLabel"] != null && r["propertyLabel"].NodeType == NodeType.Literal) { context.HtmlWriter.WriteEncodedText(" - "); context.HtmlWriter.WriteEncodedText(((ILiteralNode)r["propertyLabel"]).Value); } } context.HtmlWriter.WriteLine(); context.HtmlWriter.WriteBreak(); context.HtmlWriter.WriteLine(); // Output further information about the property IEnumerable <Triple> ts; // Output any Subproperties ts = context.Graph.GetTriplesWithSubjectPredicate(rdfsSubPropertyOf, r["property"]); this.GenerateCaptionedInformation(context, "Has Sub Properties", ts, t => t.Object); // Output Domain and Range // ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], rdfsDomain); // this.GenerateCaptionedInformation(context, "Has Domain", ts, t => t.Object); // ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], rdfsRange); // this.GenerateCaptionedInformation(context, "Has Range", ts, t => t.Object); getPropertyDomains.SetParameter("property", r["property"]); this.GenerateCaptionedInformation(context, "Has Domain", context.Graph.ExecuteQuery(getPropertyDomains) as SparqlResultSet, "domain"); getPropertyRanges.SetParameter("property", r["property"]); this.GenerateCaptionedInformation(context, "Has Range", context.Graph.ExecuteQuery(getPropertyRanges) as SparqlResultSet, "range"); // Output any Equivalent Properties ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], owlEquivalentProperty).Concat(context.Graph.GetTriplesWithPredicateObject(owlEquivalentProperty, r["property"])); this.GenerateCaptionedInformation(context, "Equivalent Properties", ts, t => t.Subject.Equals(r["property"]) ? t.Object : t.Subject); // Output any Disjoint Classes ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], owlInverseProperty).Concat(context.Graph.GetTriplesWithPredicateObject(owlInverseProperty, r["property"])); this.GenerateCaptionedInformation(context, "Inverse Property", ts, t => t.Subject.Equals(r["property"]) ? t.Object : t.Subject); // Show the Property Description if (r.HasValue("propertyDescription")) { if (r["propertyDescription"] != null && r["propertyDescription"].NodeType == NodeType.Literal) { context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P); context.HtmlWriter.Write(((ILiteralNode)r["propertyDescription"]).Value); context.HtmlWriter.RenderEndTag(); } } // End the </div> for the Property context.HtmlWriter.RenderEndTag(); context.HtmlWriter.WriteLine(); } } else { throw new RdfOutputException("Tried to make a SPARQL Query to get Property Information from the Schema but an unexpected Query Result was returned"); } } catch (RdfQueryException queryEx) { throw new RdfOutputException("Tried to make a SPARQL Query to get Property Information from the Schema but a Query Error occurred", queryEx); } // End of Page context.HtmlWriter.RenderEndTag(); //End Body context.HtmlWriter.RenderEndTag(); //End Html }
public void ParsingTurtleW3CComplexPrefixedNames9() { String input = @"p:AZazÀÖØöø˿Ͱͽ΄῾⁰↉Ⰰ⿕、ퟻ﨎ﷇﷰ𐀀󠇯"; Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C)); }
public void ParsingTurtleW3CComplexPrefixedNames2() { String input = "AZazÀÖØöø˿ͰͽͿ⁰Ⰰ、豈﷏ﷰ�𐀀�:o"; Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C)); }
/// <summary> /// Formats a Literal Node as a String. /// </summary> /// <param name="l">Literal Node.</param> /// <param name="segment">Triple Segment.</param> /// <returns></returns> protected override string FormatLiteralNode(ILiteralNode l, TripleSegment?segment) { var output = new StringBuilder(); bool longlit, plainlit; longlit = TurtleSpecsHelper.IsLongLiteral(l.Value); plainlit = TurtleSpecsHelper.IsValidPlainLiteral(l.Value, l.DataType, TurtleSyntax.Original); if (plainlit) { if (TurtleSpecsHelper.IsValidDecimal(l.Value) && l.Value.EndsWith(".")) { // Ensure we strip the trailing dot of any xsd:decimal and add a datatype definition output.Append('"'); output.Append(l.Value.Substring(0, l.Value.Length - 1)); output.Append("\"^^<"); output.Append(FormatUri(XmlSpecsHelper.XmlSchemaDataTypeDecimal)); output.Append('>'); } else { // Otherwise just write out the value output.Append(l.Value); } // For integers ensure we insert a space after the literal to ensure it can't ever be confused with a decimal if (TurtleSpecsHelper.IsValidInteger(l.Value)) { output.Append(' '); } } else { output.Append('"'); if (longlit) { output.Append("\"\""); } var value = l.Value; value = longlit ? Escape(value, _longLitMustEscape) : Escape(value, _litMustEscape); output.Append(value); output.Append('"'); if (longlit) { output.Append("\"\""); } if (!l.Language.Equals(string.Empty)) { output.Append('@'); output.Append(l.Language.ToLower()); } else if (l.DataType != null) { output.Append("^^"); if (_qnameMapper.ReduceToQName(l.DataType.AbsoluteUri, out var qname)) { if (TurtleSpecsHelper.IsValidQName(qname)) { output.Append(qname); } else { output.Append('<'); output.Append(FormatUri(l.DataType)); output.Append('>'); } } else { output.Append('<'); output.Append(FormatUri(l.DataType)); output.Append('>'); } } } return(output.ToString()); }
internal void Parse(INode n, XsdtType x) { switch (n.NodeType) { case NodeType.Uri: x.NetType = typeof(Uri); x.ValuePart = n.ToString(); x.XsdtTypeName = XsdtPrimitiveDataType.XsdtAnyUri; ConvertValueToNet(x); break; case NodeType.Literal: ILiteralNode lit = (ILiteralNode)n; x.XsdtTypeName = XsdtPrimitiveDataType.XsdtUnknown; x.ValuePart = lit.Value; if (lit.DataType != null) { if (lit.DataType.ToString().StartsWith(NamespaceMapper.XMLSCHEMA)) { x.TypePart = lit.DataType.ToString().Substring(NamespaceMapper.XMLSCHEMA.Length); } else { x.TypePart = "string"; } } else { if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value)) { if (TurtleSpecsHelper.IsValidInteger(lit.Value)) { x.TypePart = "integer"; } else if (TurtleSpecsHelper.IsValidDecimal(lit.Value)) { x.TypePart = "decimal"; } else if (TurtleSpecsHelper.IsValidDouble(lit.Value)) { x.TypePart = "double"; } else { x.TypePart = "boolean"; } } else { x.TypePart = "string"; } } foreach (int i in Enum.GetValues(typeof(XsdtPrimitiveDataType))) { var result = (XsdtPrimitiveDataType)i; XsdtAttribute attr = GetXsdtAttrFor(result); if (attr.TypeUri == x.TypePart) { x.XsdtTypeName = result; } } if (TypeLookup.ContainsKey(x.XsdtTypeName)) { x.NetType = TypeLookup[x.XsdtTypeName]; } else { throw new LinqToRdfException("XsdtTypeConverter does not know how to convert the XML Schema Datatype " + x.TypePart); } ConvertValueToNet(x); break; default: throw new LinqToRdfException("XsdtTypeConverter can only convert URI and Literal Nodes"); } }
public void ParsingTurtleOriginalPrefixedNames1() { Assert.IsTrue(TurtleSpecsHelper.IsValidQName(":a1", TurtleSyntax.Original)); }
public void ParsingTurtleW3CComplexPrefixedNames8() { String input = ":%bb"; Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C)); }
/// <summary> /// Formats a Literal Node /// </summary> /// <param name="lit">Literal Node</param> /// <param name="segment">Triple Segment</param> /// <returns></returns> protected override string FormatLiteralNode(ILiteralNode lit, TripleSegment?segment) { StringBuilder output = new StringBuilder(); if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value, lit.DataType, TurtleSyntax.Original)) { output.Append(lit.Value); } else { String value = lit.Value; if (TurtleSpecsHelper.IsLongLiteral(value)) { value = this.Escape(value, this._delimEscapes); //If there are no wrapper characters then we must escape the deliminator if (value.Contains(this._deliminatorChar)) { if (this._literalWrapperChar == null && this._longLiteralWrapperChar == null) { //Replace the deliminator value = value.Replace(new String(new char[] { this._deliminatorChar }), new String(new char[] { this._escapeChar, this._deliminatorChar })); } } //Apply appropriate wrapper characters if (this._longLiteralWrapperChar != null) { output.Append(this._longLiteralWrapperChar + value + this._longLiteralWrapperChar); } else if (this._literalWrapperChar != null) { output.Append(this._literalWrapperChar + value + this._literalWrapperChar); } else { output.Append(value); } } else { //Replace the deliminator value = this.Escape(value, this._delimEscapes); //Apply appropriate wrapper characters if (this._literalWrapperChar != null) { output.Append(this._literalWrapperChar + value + this._literalWrapperChar); } else { output.Append(value); } } if (this._fullLiteralOutput) { if (!lit.Language.Equals(String.Empty)) { output.Append("@" + lit.Language.ToLower()); } else if (lit.DataType != null) { output.Append("^^"); if (this._uriStartChar != null) { output.Append(this._uriStartChar); } if (this._uriEndChar != null) { output.Append(this.FormatUri(lit.DataType)); output.Append(this._uriEndChar); } else { output.Append(this.FormatUri(lit.DataType)); } } } } return(output.ToString()); }
public void ParsingTurtleW3CNumericLiterals1() { String input = "123.E+1"; Assert.IsTrue(TurtleSpecsHelper.IsValidDouble(input)); }
/// <summary> /// Determines whether a QName is valid /// </summary> /// <param name="value">Value</param> /// <returns></returns> protected virtual bool IsValidQName(String value) { return(TurtleSpecsHelper.IsValidQName(value)); }
private IToken TryGetNumericLiteral() { bool dotoccurred = false; bool expoccurred = false; bool signoccurred = false; if (Length == 1) { dotoccurred = true; } char next = Peek(); while (Char.IsDigit(next) || next == '-' || next == '+' || next == 'e' || next == 'E' || (next == '.' && !dotoccurred)) { // Consume the Character ConsumeCharacter(); if (next == '-' || next == '+') { if (signoccurred || expoccurred) { char last = Value[Value.Length - 2]; if (expoccurred) { if (last != 'e' && last != 'E') { // Can't occur here as isn't directly after the exponent throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent"); } } else { // Negative sign already seen throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent"); } } else { signoccurred = true; // Check this is at the start of the string if (Length > 1) { throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent"); } } } else if (next == 'e' || next == 'E') { if (expoccurred) { // Exponent already seen throw Error("Unexpected Character (Code " + (int)next + " e\nThe Exponent specifier can only occur once in a Numeric Literal"); } else { expoccurred = true; // Check that it isn't the start of the string if (Length == 1) { throw UnexpectedCharacter(next, "The Exponent specifier cannot occur at the start of a Numeric Literal"); } } } else if (next == '.') { dotoccurred = true; } next = Peek(); } // Validate the final result if (Value.EndsWith(".")) { Backtrack(); } if (!TurtleSpecsHelper.IsValidPlainLiteral(Value, TurtleSyntax.Original)) { throw Error("The format of the Numeric Literal '" + Value + "' is not valid!"); } // Return the Token LastTokenType = Token.PLAINLITERAL; return(new PlainLiteralToken(Value, CurrentLine, StartPosition, EndPosition)); }
private IToken TryGetPlainLiteralOrQName() { char next = Peek(); if (!_keywordsmode) { #region Non-Keywords Mode // Not in Keywords Mode bool colonoccurred = false; while (Char.IsLetterOrDigit(next) || next == ':' || next == '-' || next == '_') { // Consume Character ConsumeCharacter(); if (next == ':') { if (colonoccurred) { // Can't contain more than 1 Colon throw Error("Unexpected Character (Code " + (int)next + " :\nThe Colon Character can only occur once in a QName"); } else { colonoccurred = true; } } next = Peek(); } // Validate String value = Value; // If it ends in a trailing . then we need to backtrack if (value.EndsWith(".")) { Backtrack(); value = value.Substring(0, value.Length - 1); } if (value.Equals("a")) { // Keyword 'a' LastTokenType = Token.KEYWORDA; return(new KeywordAToken(CurrentLine, StartPosition)); } else if (value.Equals("is")) { // Keyword 'is' LastTokenType = Token.KEYWORDIS; return(new KeywordIsToken(CurrentLine, StartPosition)); } else if (value.Equals("of")) { // Keyword 'of' LastTokenType = Token.KEYWORDOF; return(new KeywordOfToken(CurrentLine, StartPosition)); } else if (TurtleSpecsHelper.IsValidPlainLiteral(value, TurtleSyntax.Original)) { // Other Valid Plain Literal LastTokenType = Token.PLAINLITERAL; return(new PlainLiteralToken(value, CurrentLine, StartPosition, EndPosition)); } else if (IsValidQName(value) && value.Contains(":")) { // Valid QName // Note that in the above condition we require a : since without Keywords mode // all QNames must be in a Namespace if (value.StartsWith("_:")) { // A Blank Node QName LastTokenType = Token.BLANKNODEWITHID; return(new BlankNodeWithIDToken(value, CurrentLine, StartPosition, EndPosition)); } else { // Normal QName LastTokenType = Token.QNAME; return(new QNameToken(value, CurrentLine, StartPosition, EndPosition)); } } else { // Not Valid throw Error("The value '" + value + "' is not valid as a Plain Literal or QName"); } #endregion } else { #region Keywords Mode // Since we're in Keywords Mode this is actually a QName // UNLESS it's in the Keywords list bool colonoccurred = false; while (Char.IsLetterOrDigit(next) || next == '_' || next == '-' || next == ':') { // Consume ConsumeCharacter(); if (next == ':') { if (colonoccurred) { // Can't contain more than 1 Colon throw Error("Unexpected Character (Code " + (int)next + " :\nThe Colon Character can only occur once in a QName"); } else { colonoccurred = true; } } next = Peek(); } // Validate String value = Value; // If it ends in a trailing . then we need to backtrack if (value.EndsWith(".")) { Backtrack(); value = value.Substring(0, value.Length - 1); } if (_keywords.Contains(value)) { // A Custom Keyword LastTokenType = Token.KEYWORDCUSTOM; return(new CustomKeywordToken(value, CurrentLine, StartPosition, EndPosition)); } else if (!IsValidQName(value)) { // Not a valid QName throw Error("The value '" + value + "' is not valid as a QName"); } else if (value.StartsWith("_:")) { // A Blank Node QName LastTokenType = Token.BLANKNODEWITHID; return(new BlankNodeWithIDToken(value, CurrentLine, StartPosition, EndPosition)); } else { // Return the QName LastTokenType = Token.QNAME; // If no Colon need to append it to the front to make a QName in the Default namespace if (!colonoccurred) { value = ":" + value; } return(new QNameToken(value, CurrentLine, StartPosition, EndPosition)); } #endregion } }
/// <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(new FullTripleComparer(new FastNodeComparer())); //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> /// Saves a Store in TriG (Turtle with Named Graphs) format /// </summary> /// <param name="store">Store to save</param> /// <param name="writer">Writer to save to</param> /// <param name="leaveOpen">Boolean flag indicating if <paramref name="writer"/> should be left open after the store is saved</param> public void Save(ITripleStore store, TextWriter writer, bool leaveOpen) { if (store == null) { throw new RdfOutputException("Cannot output a null Triple Store"); } if (writer == null) { throw new RdfOutputException("Cannot output to a null writer"); } TriGWriterContext context = new TriGWriterContext(store, writer, _prettyprint, _allowHiSpeed, _compressionLevel, _n3compat); // Check there's something to do if (context.Store.Graphs.Count == 0) { if (!leaveOpen) { context.Output.Close(); } return; } // Write the Header of the File foreach (var g in context.Store.Graphs) { context.NamespaceMap.Import(g.NamespaceMap); } if (context.CompressionLevel > WriterCompressionLevel.None) { // Only add @prefix declarations if compression is enabled context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap); foreach (string prefix in context.NamespaceMap.Prefixes) { if (TurtleSpecsHelper.IsValidQName(prefix + ":")) { context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">."); } } context.Output.WriteLine(); } else { context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true)); } if (_useMultiThreading) { // Standard Multi-Threaded Writing // Queue the Graphs to be written foreach (IGraph g in context.Store.Graphs) { context.Add(g.BaseUri); } // Start making the async calls List <IAsyncResult> results = new List <IAsyncResult>(); SaveGraphsDelegate d = new SaveGraphsDelegate(SaveGraphs); for (int i = 0; i < _threads; i++) { results.Add(d.BeginInvoke(context, null, null)); } // Wait for all the async calls to complete WaitHandle.WaitAll(results.Select(r => r.AsyncWaitHandle).ToArray()); RdfThreadedOutputException outputEx = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG")); foreach (IAsyncResult result in results) { try { d.EndInvoke(result); } catch (Exception ex) { outputEx.AddException(ex); } } // Make sure to close the output if (!leaveOpen) { context.Output.Close(); } // If there were any errors we'll throw an RdfThreadedOutputException now if (outputEx.InnerExceptions.Any()) { throw outputEx; } } else { try { // Optional Single Threaded Writing foreach (IGraph g in store.Graphs) { TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted); if (context.CompressionLevel > WriterCompressionLevel.None) { graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper); } else { graphContext.NodeFormatter = new UncompressedTurtleFormatter(); } context.Output.WriteLine(GenerateGraphOutput(context, graphContext)); } // Make sure to close the output if (!leaveOpen) { context.Output.Close(); } } catch { try { // Close the output if (!leaveOpen) { context.Output.Close(); } } catch { // No catch actions, just cleaning up the output stream } throw; } } }