2using System.Collections.Generic;
6using System.Threading.Tasks;
38 private readonly Dictionary<string, string> namespaces =
new Dictionary<string, string>
40 {
"xsd", XmlSchema.Namespace },
41 {
"ttl",
"http://www.w3.org/2008/turtle#" }
43 private readonly Dictionary<string, ISemanticLiteral> dataTypes =
new Dictionary<string, ISemanticLiteral>();
44 private readonly
string text;
45 private readonly
string blankNodeIdPrefix;
46 private readonly
int len;
48 private DateTimeOffset? date =
null;
49 private Uri baseUri =
null;
50 private int blankNodeIndex = 0;
68 : this(
Text, BaseUri,
"n")
93 this.len = this.text.Length;
94 this.baseUri = BaseUri;
95 this.blankNodeIdPrefix = BlankNodeIdPrefix;
98 if (!(this.baseUri is
null))
99 this.namespaces[
string.Empty] = this.baseUri.ToString();
107 public string Text => this.text;
112 public DateTimeOffset?
Date => this.date;
114 private void ParseTriples()
116 this.ParseTriples(
null);
118 if (this.pos < this.len)
126 int TriplePosition = Subject is
null ? 0 : 1;
127 bool InBlankNode = !(Subject is
null);
129 while (this.pos < this.len)
131 Object = this.ParseElement(TriplePosition);
136 else if (Predicate is
null)
152 else if (Predicate is
null)
161 switch (this.NextNonWhitespaceChar())
176 this.SkipWhiteSpace();
177 if (this.PeekNextChar() ==
'.')
213 this.SkipWhiteSpace();
214 if (this.PeekNextChars(2) ==
"{|")
221 this.ParseTriples(T);
223 this.SkipWhiteSpace();
224 if (this.NextChar() !=
'}')
233 char ch = this.NextNonWhitespaceChar();
241 string s = this.ParseName();
246 ch = this.NextNonWhitespaceChar();
250 this.baseUri = this.ParseUri().
Uri;
252 if (this.NextNonWhitespaceChar() !=
'.')
258 this.SkipWhiteSpace();
260 s = this.ParseName();
262 if (this.NextNonWhitespaceChar() !=
':')
265 if (this.NextNonWhitespaceChar() !=
'<')
268 this.namespaces[s] = this.ParseUri().
Uri.ToString();
270 if (this.NextNonWhitespaceChar() !=
'.')
281 if (TriplePosition == 1)
285 this.ParseTriples(Node);
287 if (TriplePosition == 0)
289 this.SkipWhiteSpace();
290 if (this.PeekNextChar() ==
'.')
293 return this.ParseElement(0);
300 return this.ParseCollection();
306 if (this.PeekNextChar() ==
'<')
314 if (this.NextNonWhitespaceChar() !=
'>')
317 if (this.NextNonWhitespaceChar() !=
'>')
323 return this.ParseUri();
327 if (TriplePosition != 2)
330 if (this.pos < this.len - 1 && this.text[this.pos] == ch && this.text[this.pos + 1] == ch)
333 s = this.ParseString(ch,
true,
true);
336 s = this.ParseString(ch,
false,
true);
338 string Language =
null;
340 if (this.pos < this.len && this.text[this.pos] ==
'@')
343 Language = this.ParseName();
346 if (this.pos < this.len - 1 && this.text[this.pos] ==
'^' && this.text[this.pos + 1] ==
'^')
350 string DataType = this.ParseUriOrPrefixedToken().
Uri.ToString();
352 if (!this.dataTypes.TryGetValue(DataType, out
ISemanticLiteral LiteralType))
357 this.dataTypes[DataType] = LiteralType;
360 return LiteralType.Parse(s, DataType, Language);
362 else if (!
string.IsNullOrEmpty(Language))
368 return this.ParsePrefixedToken(
string.Empty);
371 if (
char.IsWhiteSpace(ch))
376 if (this.NextNonWhitespaceChar() !=
':')
381 else if (
char.IsLetter(ch) || ch ==
':')
384 s = this.ParseName();
386 if (this.PeekNextChar() ==
':')
389 return this.ParsePrefixedToken(s);
395 if (TriplePosition == 1)
400 if (TriplePosition == 2)
405 if (TriplePosition == 2)
414 if (TriplePosition != 2)
418 return this.ParseNumber();
427 return new BlankNode(this.blankNodeIdPrefix + Guid.NewGuid().ToString());
429 return new BlankNode(this.blankNodeIdPrefix + (++this.blankNodeIndex).
ToString());
434 LinkedList<ISemanticElement> Elements =
null;
436 this.SkipWhiteSpace();
438 while (this.pos < this.len)
440 if (this.text[this.pos] ==
')')
444 if (Elements is
null)
447 LinkedListNode<ISemanticElement> Loop = Elements.First;
448 BlankNode Result = this.CreateBlankNode();
451 while (!(Loop is
null))
474 if (Elements is
null)
475 Elements =
new LinkedList<ISemanticElement>();
477 Elements.AddLast(Element);
478 this.SkipWhiteSpace();
484 private UriNode ParseUriOrPrefixedToken()
486 if (this.pos >= this.len)
489 if (this.text[this.pos] ==
'<')
492 return this.ParseUri();
495 string Prefix = this.ParseName();
497 if (this.NextChar() !=
':')
500 return this.ParsePrefixedToken(Prefix);
503 private UriNode ParsePrefixedToken(
string Prefix)
505 if (!this.namespaces.TryGetValue(Prefix, out
string Namespace))
508 this.SkipWhiteSpace();
510 string LocalName = this.ParseName();
512 return new UriNode(
new Uri(Namespace + LocalName), Prefix +
":" + LocalName);
515 private string ParseName()
520 int Start = this.pos++;
525 return this.text.Substring(Start, this.pos - Start);
547 else if (ch <
'\xc0')
549 else if (ch <=
'\xd6')
551 else if (ch <
'\xd8')
553 else if (ch <=
'\xf6')
555 else if (ch <
'\xf8')
557 else if (ch <=
'\x02ff')
559 else if (ch <
'\x0370')
561 else if (ch <=
'\x037d')
563 else if (ch <
'\x037f')
565 else if (ch <=
'\x1fff')
567 else if (ch <
'\x037f')
569 else if (ch <=
'\x1fff')
571 else if (ch <
'\x200c')
573 else if (ch <=
'\x200d')
575 else if (ch <
'\x2070')
577 else if (ch <=
'\x218f')
579 else if (ch <
'\x2C00')
581 else if (ch <=
'\x2FEF')
583 else if (ch <
'\x3001')
585 else if (ch <=
'\xD7FF')
587 else if (ch <
'\xF900')
589 else if (ch <=
'\xFDCF')
591 else if (ch <
'\xFDF0')
593 else if (ch <=
'\xFFFD')
616 else if (ch <
'\x00B7')
618 else if (ch ==
'\x00B7')
620 else if (ch <
'\x0300')
622 else if (ch <=
'\x036F')
624 else if (ch <
'\x203F')
626 else if (ch <=
'\x2040')
634 int Start = this.pos;
635 char ch = this.PeekNextChar();
636 bool HasDigits =
false;
637 bool HasDecimal =
false;
638 bool HasExponent =
false;
640 if (ch ==
'+' || ch ==
'-')
643 ch = this.PeekNextChar();
646 while (
char.IsDigit(ch))
649 ch = this.PeekNextChar();
657 ch = this.PeekNextChar();
659 while (
char.IsDigit(ch))
662 ch = this.PeekNextChar();
666 if (ch ==
'e' || ch ==
'E')
670 ch = this.PeekNextChar();
672 if (ch ==
'+' || ch ==
'-')
675 ch = this.PeekNextChar();
678 while (
char.IsDigit(ch))
681 ch = this.PeekNextChar();
685 if (this.pos > Start)
687 string s = this.text.Substring(Start, this.pos - Start);
705 if (BigInteger.TryParse(s, out BigInteger bi))
715 private string ParseString(
char EndChar,
bool MultiLine,
bool IncludeWhiteSpace)
717 StringBuilder sb =
null;
718 int Start = this.pos;
721 while ((ch = this.PeekNextChar()) != (
char)0)
729 if (this.pos < this.len - 1 && this.text[this.pos] == EndChar && this.text[this.pos + 1] == EndChar)
732 return sb?.ToString() ?? this.text.Substring(Start, this.pos - Start - 3);
738 return sb?.ToString() ?? this.text.Substring(Start, this.pos - Start - 1);
744 sb =
new StringBuilder();
746 if (this.pos > Start + 1)
747 sb.Append(this.text.Substring(Start,
this.pos - Start - 1));
750 switch (ch = this.NextChar())
784 if (this.pos < this.len - 3 &&
int.TryParse(this.text.Substring(
this.pos, 4), System.Globalization.NumberStyles.HexNumber,
null, out
int i))
794 if (this.pos < this.len - 7 &&
int.TryParse(this.text.Substring(
this.pos, 8), System.Globalization.NumberStyles.HexNumber,
null, out i))
808 else if (IncludeWhiteSpace || !
char.IsWhiteSpace(ch))
812 throw this.
ParsingException(
"Expected " +
new string(EndChar, MultiLine ? 3 : 1));
822 string Short = this.ParseString(
'>',
false,
false);
824 if (this.baseUri is
null)
826 if (Uri.TryCreate(Short, UriKind.RelativeOrAbsolute, out Uri URI))
827 return new UriNode(URI, Short);
833 if (
string.IsNullOrEmpty(Short))
834 return new UriNode(this.baseUri, Short);
835 else if (Uri.TryCreate(
this.baseUri, Short, out Uri URI))
836 return new UriNode(URI, Short);
842 private void SkipLine()
846 while ((ch = this.PeekNextChar()) !=
'\r' && ch !=
'\n' && ch != 0)
850 private void SkipWhiteSpace()
856 ch = this.PeekNextChar();
858 if (
char.IsWhiteSpace(ch))
867 private char PeekNextChar()
869 if (this.pos < this.len)
870 return this.text[this.pos];
875 private string PeekNextChars(
int NrChars)
877 if (this.pos + NrChars <= this.len)
878 return this.text.Substring(this.pos, NrChars);
883 private char NextChar()
885 if (this.pos < this.len)
887 char ch = this.text[this.pos++];
891 if (this.pos < this.len)
892 ch = this.text[this.pos++];
903 private char NextNonWhitespaceChar()
909 ch = this.NextChar();
911 while (ch != 0 &&
char.IsWhiteSpace(ch));
922 this.date = HttpResponse.Headers.Date;
923 return Task.CompletedTask;
Helps with parsing of commong data types.
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Represents a bool literal.
Represents a custom literal.
Represents a decimal literal.
Represents a double literal.
Represents an integer literal of undefined size.
Represents a string literal.
Abstract base class for semantic literal values.
Implements a semantic triple.
Contains semantic information stored in an RDF document.
static UriNode RdfType
rdf:type predicate
static UriNode RdfNil
Predefined reference to end of collection.
static UriNode RdfRest
Predefined reference to next element in a collection.
static UriNode RdfFirst
Predefined reference to first element in a collection.
Contains semantic information stored in a turtle document. https://www.w3.org/TR/rdf12-turtle/ https:...
override void Add(ISemanticTriple Triple)
Adds a triple to the cube.
string Text
Original text of document.
TurtleDocument(string Text)
Contains semantic information stored in a turtle document.
Task DecodeMetaInformation(HttpResponseMessage HttpResponse)
Decodes meta-information available in the HTTP Response.
DateTimeOffset? Date
Server timestamp of document.
static bool IsNameChar(char ch)
Checks if a character can be included in a name.
static bool IsNameStartChar(char ch)
Checks if a character is a character that can start a name.
TurtleDocument(string Text, Uri BaseUri, string BlankNodeIdPrefix)
Contains semantic information stored in a turtle document.
TurtleDocument(string Text, Uri BaseUri)
Contains semantic information stored in a turtle document.
TurtleDocument(string Text, Uri BaseUri, string BlankNodeIdPrefix, BlankNodeIdMode BlankNodeIdMode)
Contains semantic information stored in a turtle document.
Static class that dynamically manages types and interfaces available in the runtime environment.
Interface for content classes, that process information available in HTTP headers in the response.
Interface for semantic nodes.
Interface for semantic literals.
Interface for semantic triples.
ISemanticElement Object
Object element
ISemanticElement Predicate
Predicate element
ISemanticElement Subject
Subject element
BlankNodeIdMode
How blank node IDs are generated
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.
Prefix
SI prefixes. http://physics.nist.gov/cuu/Units/prefixes.html