private string PrintValueNode(Node node) { if (node is Node <UriOrBlank> refNode) { return(PrintLinkNode(refNode)); } if (node is Node <Text> textNode) { var val = textNode.Value; return($"\"{ValueEncoder.LiteralEscape(val.Value)}\"" + $"@{val.Language}"); } //only write a node with var dataType = node.ValueType.DataType == XMLSchema.String? "" : "^^<" + ValueEncoder.UriEscape(node.ValueType.DataType) + ">"; if (node.ValueString is null) { throw new Exception("cannot print node without value string"); } return($"\"{ValueEncoder.LiteralEscape(node.ValueString)}\"{dataType}"); }
private string PrintLinkNode(Node <UriOrBlank> node) { if (node is BlankNode b) { return(b.Scope == _g.Id ? "_:" + b.Label : throw new BlankNodeScopedToInvalidGraph()); } if (node is UriNode u) { return($"<{ValueEncoder.UriEscape(u.Uri)}>"); } throw new Exception($"Unknown {nameof(UriOrBlank)} node"); }
/// <summary> /// Create token by scanning source data. /// </summary> public static Token NextToken(ReadOnlySpan <char> data) { if (data.IsEmpty) { return(Token.Invalid(data)); } if (char.IsWhiteSpace(data[0])) { return(new Token( NTripleTokenType.Whitespace, data.Slice(0, 1), data.Slice(1))); } if (data[0] == '.') { return(new Token( NTripleTokenType.Dot, data.Slice(0, 1), data.Slice(1))); } int end; if (data[0] == '"') { end = -1; var escape = false; for (var i = 1; i < data.Length; i++) { if (data[i] == '"' && !escape) { end = i; break; } //skip \\ if (data[i] == '\\' && i + 1 < data.Length && data[i + 1] == '\\') { i++; continue; } escape = data[i] == '\\'; } if (end < 0) { return(Token.Invalid(data)); } return(new Token( NTripleTokenType.Literal, data.Slice(1, end - 1), data.Slice(end + 1) )); } if (data[0] == '<') { end = data.IndexOf(">"); if (end < 0) { return(Token.Invalid(data)); } var val = ValueEncoder.LiteralUnEscape(data.Slice(1, end - 1)); return(new Token( NTripleTokenType.Uri, val, data.Slice(end + 1))); } if (data[0] == '#') { //safe for EOL \r\n or \n end = data.IndexOf('\n'); if (end < 0) { end = data.Length; } var remainder = end == data.Length ? ReadOnlySpan <char> .Empty : data.Slice(end + 1); if (data[end - 1] == '\r') { end--; } var value = end == data.Length ? data.Slice(1) : data.Slice(1, end); return(new Token(NTripleTokenType.Comment, value, remainder)); } if (data.StartsWith("_:")) { end = 2; if (end == data.Length || IsInvalidBlankStartChar(data[end])) { throw new Exception( "Blank label cannot start with a " + (end == data.Length ? "no-char" : data[end].ToString())); } for (end = 3; end < data.Length; end++) { var ch = data[end]; if (!IsValidBlankChar(ch)) { end--; break; } } if (end == data.Length) { end--; } //cannot end on a . if (data[end] == '.') { end--; } var rest = end + 1 < data.Length ? data.Slice(end + 1) : ReadOnlySpan <char> .Empty; return(new Token( NTripleTokenType.Blank, data.Slice(2, end - 1), rest)); } if (data[0] == '@') { end = IndexOfWhitespace(data); if (end < 0) { return(Token.Invalid(data)); } return(new Token( NTripleTokenType.Language, data.Slice(1, end - 1), data.Slice(end) )); } if (data.StartsWith("^^<")) { end = data.IndexOf('>'); if (end < 0) { return(Token.Invalid(data)); } return(new Token(NTripleTokenType.DataType, data.Slice(3, end - 3), data.Slice(end + 1))); } return(Token.Invalid(data)); }
/// <summary> /// Handle the next <see cref="NTripleTokenizer.Token"/> /// </summary> public void Next(NTripleTokenizer.Token token) { if (token.Type == NTripleTokenType.Invalid) { throw new Exception("Invalid token"); } if (token.Type == NTripleTokenType.Whitespace) { return; } if (token.Type == NTripleTokenType.Comment) { return; } if (_subject is null) { if (token.Type == NTripleTokenType.Uri) { IsValidUri(token.Value); _subject = _graph.Uri(ValueEncoder.UriUnEscape(token.Value)); return; } if (token.Type == NTripleTokenType.Blank) { _subject = _graph.Blank(token.Value); return; } throw new Exception("Expected uri for subject"); } if (_predicate is null) { if (token.Type == NTripleTokenType.Uri) { IsValidUri(token.Value); _predicate = _graph.Uri( ValueEncoder.UriUnEscape(token.Value)); return; } throw new Exception("Expected uri for predicate"); } if (_object is null) { if (token.Type == NTripleTokenType.Uri) { IsValidUri(token.Value); _object = _graph.Uri(token.Value); return; } if (token.Type == NTripleTokenType.Blank) { _object = _graph.Blank(token.Value); return; } if (_objectParts is null) { if (token.Type != NTripleTokenType.Literal) { throw new Exception("expected literal for object value"); } _objectParts = new ObjectParts { Literal = ValueEncoder.LiteralUnEscape(token.Value) }; return; } if (token.Type == NTripleTokenType.Language) { IsValidLanguageTag(token.Value); _objectParts.Lang = new string(token.Value); return; } if (token.Type == NTripleTokenType.DataType) { IsValidUri(token.Value); _objectParts.ValueType = new string(token.Value); return; } } if (token.Type != NTripleTokenType.Dot) { throw new Exception("Expected dot to end triple."); } if (_object is null && _objectParts != null) { _object = _graph.NewNode(_objectParts.Literal, ValueEncoder.UriUnEscape(_objectParts.ValueType), _objectParts.Lang); } if (_object is null) { throw new Exception("Expected object to be created"); } _graph.Assert(_subject, _predicate, _object); //reset for next triple. _subject = null; _predicate = null; _object = null; _objectParts = null; }