/// <summary> /// Parser method which parses a Binding Object which occurs in the array of Bindings /// </summary> private void ParseBinding(SparqlJsonParserContext context, bool headSeen) { //Can we read some properties if (context.Input.Read()) { SparqlResult result = new SparqlResult(); while (context.Input.TokenType != JsonToken.EndObject) { if (context.Input.TokenType == JsonToken.PropertyName) { //Each Property Name should be for a variable this.ParseBoundVariable(context, context.Input.Value.ToString(), result, headSeen); } else { throw Error(context, "Unexpected Token '" + context.Input.TokenType + "' with value '" + context.Input.Value + "' encountered, expected a Property Name giving the Binding for a Variable for this Result"); } //Get Next Token if (!context.Input.Read()) { throw new RdfParseException("Unexpected End of Input while trying to parse a Binding Object"); } } //Check that all Variables are bound for a given result binding nulls where appropriate foreach (String v in context.Variables) { if (!result.HasValue(v)) { result.SetValue(v, null); } } //Add to Results result.SetVariableOrdering(context.Variables); if (!context.Handler.HandleResult(result)) { ParserHelper.Stop(); } } else { throw new RdfParseException("Unexpected End of Input while trying to parse a Binding Object"); } }
private void TryParseResultRow(TokenisingResultParserContext context) { IToken next = context.Tokens.Peek(); if (next.TokenType == Token.EOF) { context.Tokens.Dequeue(); return; } bool allowEOL = true, expectTab = false; int v = 0; SparqlResult result = new SparqlResult(); while (true) { next = context.Tokens.Dequeue(); switch (next.TokenType) { case Token.URI: if (expectTab) { throw ParserHelper.Error("Unexpected URI, expected a Tab between RDF Terms", next); } if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } INode uri = ParserHelper.TryResolveUri(context, next); result.SetValue(context.Variables[v], uri); v++; allowEOL = true; expectTab = true; break; case Token.BLANKNODEWITHID: if (expectTab) { throw ParserHelper.Error("Unexpected Blank Node, expected a Tab between RDF Terms", next); } if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } INode blank = context.Handler.CreateBlankNode(next.Value.Substring(2)); result.SetValue(context.Variables[v], blank); v++; allowEOL = true; expectTab = true; break; case Token.LITERAL: case Token.LONGLITERAL: case Token.PLAINLITERAL: if (expectTab) { throw ParserHelper.Error("Unexpected Blank Node, expected a Tab between RDF Terms", next); } if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } INode lit = TryParseLiteral(context, next); result.SetValue(context.Variables[v], lit); v++; allowEOL = true; expectTab = true; break; case Token.EOL: if (allowEOL) { break; } else { if (v == context.Variables.Count - 1) { // If this is the last expected term then this must be an empty term v++; break; } throw ParserHelper.Error("Unexpected End of Line, expected a RDF Term Token", next); } case Token.TAB: if (!expectTab) { // This is an empty field if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } v++; } expectTab = false; allowEOL = false; break; case Token.EOF: if (!allowEOL) { throw ParserHelper.Error("Unexpected EOF, expected another RDF Term for the Result Row", next); } break; default: throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next); } // Stop when we've hit the End of the Line/File if (next.TokenType == Token.EOL || next.TokenType == Token.EOF) { break; } } if (v < context.Variables.Count) { throw ParserHelper.Error("Too few RDF Terms, got " + v + " but expected " + context.Variables.Count, next); } result.SetVariableOrdering(context.Variables); if (!context.Handler.HandleResult(result)) { ParserHelper.Stop(); } }
private void TryParseResultRow(TokenisingResultParserContext context) { IToken next = context.Tokens.Peek(); if (next.TokenType == Token.EOF) { context.Tokens.Dequeue(); return; } bool allowEOL = true, expectComma = false; int v = 0; SparqlResult result = new SparqlResult(); while (true) { next = context.Tokens.Dequeue(); switch (next.TokenType) { case Token.BLANKNODEWITHID: if (expectComma) { throw ParserHelper.Error("Unexpected Blank Node, expected a comma between RDF Terms", next); } if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } INode blank = context.Handler.CreateBlankNode(next.Value.Substring(2)); result.SetValue(context.Variables[v], blank); v++; allowEOL = true; expectComma = true; break; case Token.LITERAL: case Token.PLAINLITERAL: if (expectComma) { throw ParserHelper.Error("Unexpected Blank Node, expected a comma between RDF Terms", next); } if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } // Try and guess what kind of term this is String lexicalForm = next.Value; INode value; if (lexicalForm.StartsWith("http://") || lexicalForm.StartsWith("https://") || lexicalForm.StartsWith("mailto:") || lexicalForm.StartsWith("ftp://")) { try { // Guessing a URI if starts with common URI prefix value = ParserHelper.TryResolveUri(context, next); } catch { // If invalid URI fall back to treating as literal value = context.Handler.CreateLiteralNode(lexicalForm); } } else { value = context.Handler.CreateLiteralNode(lexicalForm); } result.SetValue(context.Variables[v], value); v++; allowEOL = true; expectComma = true; break; case Token.EOL: if (allowEOL) { break; } else { if (v == context.Variables.Count - 1) { // If this is the last expected term then this must be an empty term v++; break; } throw ParserHelper.Error("Unexpected End of Line, expected a RDF Term Token", next); } case Token.COMMA: if (!expectComma) { // This is an empty field if (v >= context.Variables.Count) { throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next); } v++; } expectComma = false; allowEOL = false; break; case Token.EOF: if (!allowEOL) { throw ParserHelper.Error("Unexpected EOF, expected another RDF Term for the Result Row", next); } break; default: throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next); } // Stop when we've hit the End of the Line/File if (next.TokenType == Token.EOL || next.TokenType == Token.EOF) { break; } } result.SetVariableOrdering(context.Variables); if (!context.Handler.HandleResult(result)) { ParserHelper.Stop(); } }
/// <summary> /// Parses the XML Result Set format into a set of SPARQLResult objects /// </summary> /// <param name="context">Parser Context</param> private void Parse(SparqlXmlParserContext context) { try { context.Handler.StartResults(); // Get the Document Element and check it's a Sparql element if (!context.Input.Read()) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as it was not possible to read a document element from the input"); } while (context.Input.NodeType != XmlNodeType.Element) { if (!context.Input.Read()) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as it was not possible to read a document element from the input"); } } if (!context.Input.Name.Equals("sparql")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set from the provided XML since the Document Element is not a <sparql> element!"); } // Go through it's attributes and check the Namespace is specified bool nsfound = false; if (context.Input.HasAttributes) { for (int i = 0; i < context.Input.AttributeCount; i++) { context.Input.MoveToNextAttribute(); if (context.Input.Name.Equals("xmlns")) { if (!context.Input.Value.Equals(SparqlSpecsHelper.SparqlNamespace)) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <sparql> element has an incorrect Namespace!"); } else { nsfound = true; } } } } if (!nsfound) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <sparql> element fails to specify the SPARQL Namespace!"); } // Get the Variables from the Header if (!context.Input.Read()) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as could not read a <head> element from the input"); } if (!context.Input.Name.Equals("head")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the first Child Node of the <sparql> element is not the required <head> element!"); } // Only parser <variable> and <link> elements if not an empty <head /> element if (!context.Input.IsEmptyElement) { while (context.Input.Read()) { // Stop reading when we hit the </head> if (context.Input.NodeType == XmlNodeType.EndElement && context.Input.Name.Equals("head")) { break; } // Looking for <variable> elements if (context.Input.Name.Equals("variable")) { // Should only have 1 attribute if (context.Input.AttributeCount != 1) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <variable> element has too few/many attributes, only a 'name' attribute should be present!"); } else { // Add the Variable to the list context.Input.MoveToNextAttribute(); if (!context.Handler.HandleVariable(context.Input.Value)) { ParserHelper.Stop(); } context.Variables.Add(context.Input.Value); } } else if (context.Input.Name.Equals("link")) { // Not bothered about <link> elements } else { // Some unexpected element throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <head> contains an unexpected element <" + context.Input.Name + ">!"); } } } if (!context.Input.Name.Equals("head")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as reached the end of the input before the closing </head> element was found"); } // Look at the <results> or <boolean> element if (!context.Input.Read()) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as could not read a <results> element from the input"); } if (context.Input.Name.Equals("results")) { // Only parser <result> elements if it's not an empty <results /> element if (!context.Input.IsEmptyElement) { while (context.Input.Read()) { // Stop reading when we hit the </results> if (context.Input.NodeType == XmlNodeType.EndElement && context.Input.Name.Equals("results")) { break; } // Must be a <result> element if (!context.Input.Name.Equals("result")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <results> element contains an unexpected element <" + context.Input.Name + ">!"); } // Empty Elements generate an Empty Result if (context.Input.IsEmptyElement) { if (!context.Handler.HandleResult(new SparqlResult())) { ParserHelper.Stop(); } continue; } // Get the values of each Binding String var; INode value; SparqlResult result = new SparqlResult(); while (context.Input.Read()) { // Stop reading when we hit the </binding> if (context.Input.NodeType == XmlNodeType.EndElement && context.Input.Name.Equals("result")) { break; } // Must be a <binding> element if (!context.Input.Name.Equals("binding")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <result> element contains an unexpected element <" + context.Input.Name + ">!"); } // Must have only 1 attribute if (context.Input.AttributeCount != 1) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <binding> element has too few/many attributes, only a 'name' attribute should be present!"); } // Get the Variable this is a binding for and its Value context.Input.MoveToNextAttribute(); var = context.Input.Value; if (!context.Input.Read()) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as reached the end of input when the contents of a <binding> element was expected"); } value = ParseValue(context); // Check that the Variable was defined in the Header if (!context.Variables.Contains(var)) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <binding> element attempts to bind a value to the variable '" + var + "' which is not defined in the <head> by a <variable> element!"); } // Set the Variable to the Value result.SetValue(var, value); } // Check that all Variables are bound for a given result binding nulls where appropriate foreach (String v in context.Variables) { if (!result.HasValue(v)) { result.SetValue(v, null); } } if (!context.Input.Name.Equals("result")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as reached the end of the input before a closing </result> element was found"); } // Add to results set result.SetVariableOrdering(context.Variables); if (!context.Handler.HandleResult(result)) { ParserHelper.Stop(); } } } if (!context.Input.Name.Equals("results")) { throw new RdfParseException("Unable to Parse a SPARQL Result Set as reached the end of the input before the closing </results> element was found"); } } else if (context.Input.Name.Equals("boolean")) { // Can't be any <variable> elements if (context.Variables.Count > 0) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <boolean> element is specified but the <head> contained one/more <variable> elements which is not permitted!"); } try { // Get the value of the <boolean> element as a Boolean Boolean b = Boolean.Parse(context.Input.ReadInnerXml()); context.Handler.HandleBooleanResult(b); } catch (Exception) { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the <boolean> element contained a value that could not be understood as a Boolean value!"); } } else { throw new RdfParseException("Unable to Parse a SPARQL Result Set since the second Child Node of the <sparql> element is not the required <results> or <boolean> element!"); } context.Handler.EndResults(true); } catch (RdfParsingTerminatedException) { context.Handler.EndResults(true); } catch { // Some other Error context.Handler.EndResults(false); throw; } }