/// <summary> /// Extracts the corresponding value from the SemWeb results for a member access projection. /// </summary> /// <param name="vb">The SemWeb results.</param> /// <returns>the value that was extracted (and converted) from the results.</returns> private object ExtractMemberAccess(SparqlResult vb) { // work out if the SelectExpression really is a member access var ue = (SelectExpression).Arguments[1] as UnaryExpression; if (ue == null) { throw new ArgumentException("incompatible expression type"); } var le = ue.Operand as LambdaExpression; if (le == null) { throw new LinqToRdfException("Incompatible expression type found when building ontology projection"); } if (le.Body is MemberExpression) { // work out which member is being queried on var memberExpression = (MemberExpression)le.Body; MemberInfo memberInfo = memberExpression.Member; // get its name and use that as a key into the results //string vVal = vb[memberInfo.Name].ToString(); // convert the result from XSDT format to .NET types if (!vb.HasValue(memberInfo.Name)) { return(null); } var tc = new XsdtTypeConverter(); return(tc.Parse(vb[memberInfo.Name])); //return tc.Parse(vVal); } return(null); }
private static bool CompareSolutions(SparqlResult x, SparqlResult y, Dictionary <string, string> bnodeMap) { var boundVarsX = x.Variables.Where(v => x.HasValue(v) && x.Value(v) != null); var boundVarsY = y.Variables.Where(v => y.HasValue(v) && y.Value(v) != null); if (!boundVarsX.Any() && !boundVarsY.Any()) { return(true); } if (x.Variables.Count().Equals(y.Variables.Count()) && x.Variables.All(xv => y.Variables.Contains(xv))) { foreach (var xv in x.Variables) { var xb = x[xv]; var yb = y[xv]; if (!CompareNodes(xb, yb, bnodeMap)) { return(false); } } return(true); } return(false); }
protected override void ProcessResult(SparqlResult result) { var nvc = new NameValueCollection(); foreach (string varName in varNames) { if (!result.HasValue(varName)) continue; INode resource = result[varName]; if (resource.NodeType == NodeType.Uri) { if (string.IsNullOrEmpty(@namespace) || ((IUriNode)resource).ToString().StartsWith(@namespace)) { nvc[varName] = resource.ToString(); } } else if (resource.NodeType == NodeType.Blank && !ignoreBnodes) { var bn = resource as BlankNode; if (string.IsNullOrEmpty(@namespace) || bn.InternalID.StartsWith(@namespace)) { nvc[varName] = bn.InternalID; } } } bindings.Add(nvc); }
protected override void ProcessResult(SparqlResult result) { var nvc = new NameValueCollection(); foreach (string varName in varNames) { if (!result.HasValue(varName)) { continue; } INode resource = result[varName]; if (resource.NodeType == NodeType.Uri) { if (string.IsNullOrEmpty(@namespace) || ((IUriNode)resource).ToString().StartsWith(@namespace)) { nvc[varName] = resource.ToString(); } } else if (resource.NodeType == NodeType.Blank && !ignoreBnodes) { var bn = resource as BlankNode; if (string.IsNullOrEmpty(@namespace) || bn.InternalID.StartsWith(@namespace)) { nvc[varName] = bn.InternalID; } } } bindings.Add(nvc); }
/// <summary> /// Formats a SPARQL Result /// </summary> /// <param name="result">SPARQL Result</param> /// <returns></returns> public string Format(SparqlResult result) { StringBuilder output = new StringBuilder(); output.AppendLine(" <result>"); foreach (String var in result.Variables) { if (result.HasValue(var)) { INode value = result[var]; if (value != null) { output.Append(" <binding name=\"" + var + "\">"); switch (value.NodeType) { case NodeType.Blank: output.Append("<bnode>" + ((IBlankNode)value).InternalID + "</bnode>"); break; case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("SPARQL XML Results")); case NodeType.Literal: ILiteralNode lit = (ILiteralNode)value; output.Append("<literal"); if (lit.DataType != null) { output.Append(" datatype=\"" + WriterHelper.EncodeForXml(lit.DataType.AbsoluteUri) + "\">" + WriterHelper.EncodeForXml(lit.Value) + "</literal>"); } else if (!lit.Language.Equals(String.Empty)) { output.Append(" xml:lang=\"" + lit.Language + "\">" + lit.Value + "</literal>"); } else { output.Append(">" + WriterHelper.EncodeForXml(lit.Value) + "</literal>"); } break; case NodeType.Uri: output.Append("<uri>" + WriterHelper.EncodeForXml(value.ToString()) + "</uri>"); break; case NodeType.Variable: throw new RdfOutputException(WriterErrorMessages.VariableNodesUnserializable("SPARQL XML Results")); default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("SPARQL XML Results")); } output.AppendLine("</binding>"); } } } output.Append(" </result>"); return(output.ToString()); }
protected override void ProcessResult(SparqlResult result) { foreach (String variable in result.Variables) { if (result.HasValue(variable)) { Logger.Debug("?{0} => <{1}>", variable, result[variable]); } } }
public static T GetFieldValue <T>(this SparqlResult r, string fieldName, Func <IValuedNode, T> xform, T fallbackValue = default(T)) { if (r == null || string.IsNullOrWhiteSpace(fieldName)) { return(fallbackValue); } if (r.HasValue(fieldName) && r[fieldName] != null) { return(xform(r[fieldName].AsValuedNode())); } return(fallbackValue); }
/// <summary> /// Formats a SPARQL Result /// </summary> /// <param name="result">SPARQL Result</param> /// <returns></returns> public string Format(SparqlResult result) { StringBuilder output = new StringBuilder(); output.AppendLine(" <result>"); foreach (String var in result.Variables) { if (result.HasValue(var)) { INode value = result[var]; if (value != null) { output.Append(" <binding name=\"" + var + "\">"); switch (value.NodeType) { case NodeType.Blank: output.Append("<bnode>" + ((IBlankNode)value).InternalID + "</bnode>"); break; case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("SPARQL XML Results")); case NodeType.Literal: ILiteralNode lit = (ILiteralNode)value; output.Append("<literal"); if (lit.DataType != null) { output.Append(" datatype=\"" + WriterHelper.EncodeForXml(lit.DataType.ToString()) + "\">" + WriterHelper.EncodeForXml(lit.Value) + "</literal>"); } else if (!lit.Language.Equals(String.Empty)) { output.Append(" xml:lang=\"" + lit.Language + "\">" + lit.Value + "</literal>"); } else { output.Append(">" + WriterHelper.EncodeForXml(lit.Value) + "</literal>"); } break; case NodeType.Uri: output.Append("<uri>" + WriterHelper.EncodeForXml(value.ToString()) + "</uri>"); break; case NodeType.Variable: throw new RdfOutputException(WriterErrorMessages.VariableNodesUnserializable("SPARQL XML Results")); default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("SPARQL XML Results")); } output.AppendLine("</binding>"); } } } output.Append(" </result>"); return output.ToString(); }
/// <summary> /// Handles results by extracting strings from relevant variables. /// </summary> /// <param name="result">Result.</param> /// <returns></returns> protected override bool HandleResultInternal(SparqlResult result) { foreach (String var in result.Variables) { if (_vars.Contains(var) && result.HasValue(var)) { INode value = result[var]; if (value.NodeType == NodeType.Literal) { _values.Add(((ILiteralNode)value).Value); } } } return(true); }
/// <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"); } }
/// <summary> /// stores the result from a SemWeb result into a <see cref="PropertyInfo"/> doing whatever conversions are required. /// </summary> /// <param name="semwebBindings">The incoming result from semweb.</param> /// <param name="obj">The object instance on wqhich the property is to be set</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> identifying the property to be populated with the value stored in <see cref="semwebBindings"/>.</param> public static void PopulateProperty(SparqlResult semwebBindings, object obj, PropertyInfo propertyInfo) { if (semwebBindings.HasValue(propertyInfo.Name)) { if (semwebBindings[propertyInfo.Name] == null) { return; } var tc = new XsdtTypeConverter(); object x = tc.Parse(semwebBindings[propertyInfo.Name]); if (x is IConvertible) { propertyInfo.SetValue(obj, Convert.ChangeType(x, propertyInfo.PropertyType), null); } else // if it's not convertible, it could be because the type is an MS XSDT type rather than a .NET primitive if (x.GetType().Namespace == "System.Runtime.Remoting.Metadata.W3cXsd2001") { switch (x.GetType().Name) { case "SoapDate": var d = (SoapDate)x; propertyInfo.SetValue(obj, Convert.ChangeType(d.Value, propertyInfo.PropertyType), null); break; default: break; } } else if (propertyInfo.PropertyType == typeof(string)) { propertyInfo.SetValue(obj, x.ToString(), null); } } }
/// <summary> /// Parser method which parses a Binding Object which occurs in the array of Bindings /// </summary> private void ParseBinding(SparqlJsonParserContext context) { //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); } else { throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' 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 if (!context.Handler.HandleResult(result)) throw ParserHelper.Stop(); } else { throw new RdfParseException("Unexpected End of Input while trying to parse a Binding Object"); } }
/// <summary> /// Extracts the corresponding value from the SemWeb results for a member access projection. /// </summary> /// <param name="vb">The SemWeb results.</param> /// <returns>the value that was extracted (and converted) from the results.</returns> private object ExtractMemberAccess(SparqlResult vb) { // work out if the SelectExpression really is a member access var ue = (SelectExpression).Arguments[1] as UnaryExpression; if (ue == null) throw new ArgumentException("incompatible expression type"); var le = ue.Operand as LambdaExpression; if (le == null) throw new LinqToRdfException("Incompatible expression type found when building ontology projection"); if (le.Body is MemberExpression) { // work out which member is being queried on var memberExpression = (MemberExpression) le.Body; MemberInfo memberInfo = memberExpression.Member; // get its name and use that as a key into the results //string vVal = vb[memberInfo.Name].ToString(); // convert the result from XSDT format to .NET types if (!vb.HasValue(memberInfo.Name)) return null; var tc = new XsdtTypeConverter(); return tc.Parse(vb[memberInfo.Name]); //return tc.Parse(vVal); } return null; }
/// <summary> /// stores the result from a SemWeb result into a <see cref="PropertyInfo"/> doing whatever conversions are required. /// </summary> /// <param name="semwebBindings">The incoming result from semweb.</param> /// <param name="obj">The object instance on wqhich the property is to be set</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> identifying the property to be populated with the value stored in <see cref="semwebBindings"/>.</param> public static void PopulateProperty(SparqlResult semwebBindings, object obj, PropertyInfo propertyInfo) { if (semwebBindings.HasValue(propertyInfo.Name)) { if (semwebBindings[propertyInfo.Name] == null) return; var tc = new XsdtTypeConverter(); object x = tc.Parse(semwebBindings[propertyInfo.Name]); if (x is IConvertible) propertyInfo.SetValue(obj, Convert.ChangeType(x, propertyInfo.PropertyType), null); else // if it's not convertible, it could be because the type is an MS XSDT type rather than a .NET primitive if (x.GetType().Namespace == "System.Runtime.Remoting.Metadata.W3cXsd2001") { switch (x.GetType().Name) { case "SoapDate": var d = (SoapDate) x; propertyInfo.SetValue(obj, Convert.ChangeType(d.Value, propertyInfo.PropertyType), null); break; default: break; } } else if (propertyInfo.PropertyType == typeof (string)) { propertyInfo.SetValue(obj, x.ToString(), null); } } }
/// <summary> /// A callback interface that gets called by SemWeb when results are sent /// back from a remote SPARQL source. This gets each unique set of bindings /// in turn. It can either store the results or deserialise them on the spot. /// </summary> /// <returns>true if the deserialiser was able to use the result or false otherwise</returns> protected override void ProcessResult(SparqlResult result) { #region Tracing #line hidden if (Logger.IsDebugEnabled) { Logger.Debug("Got Result {0}.", result.ToString()); } #line default #endregion if (IsSelectMember(SelectExpression)) { IncomingResults.Add(ExtractMemberAccess(result)); return; } if (originalType == null) throw new LinqToRdfException("need ontology type to create"); object t; IEnumerable<MemberInfo> props = GetPropertiesToPopulate(originalType, instanceType); if (originalType == instanceType) { #region not using a projection t = Activator.CreateInstance(instanceType); #region Tracing #line hidden if (Logger.IsDebugEnabled) { Logger.Debug("created new instance of {0}.", t.GetType().Name); } #line default #endregion AssignDataContext(t as OwlInstanceSupertype, DataContext); AssignInstanceUri(t as OwlInstanceSupertype, InstanceName, result); foreach (PropertyInfo pi in props) { if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition().Name.StartsWith("Entity")) continue; try { PopulateProperty(result, t, pi); } catch (ArgumentException ae) { #region Tracing #line hidden if (Logger.IsErrorEnabled) { Logger.ErrorEx("Unable to populate property " + pi.Name, ae); Logger.Error("continuing"); } #line default #endregion } catch (Exception e) { #region Tracing #line hidden if (Logger.IsErrorEnabled) { Logger.ErrorEx("Unable to populate property " + pi.Name, e); } #line default #endregion return; } } #endregion } else { #region using a projection var args = new List<object>(); foreach (PropertyInfo pi in props) { try { if (result.HasValue(pi.Name)) { if (result[pi.Name] != null) { string vVal = result[pi.Name].ToString(); vVal = RemoveEnclosingQuotesOnString(vVal, pi); if (IsXsdtEncoded(vVal)) vVal = DecodeXsdtString(vVal); args.Add(Convert.ChangeType(vVal, pi.PropertyType)); } } } catch (Exception e) { Console.WriteLine(e); return; } } t = Activator.CreateInstance(instanceType, args.ToArray()); #endregion } if (Distinct) { if (ObjectIsUniqueSoFar(t as OwlInstanceSupertype)) IncomingResults.Add(t); } else IncomingResults.Add(t); return; }
/// <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 = this.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 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; } }
/// <summary> /// A callback interface that gets called by SemWeb when results are sent /// back from a remote SPARQL source. This gets each unique set of bindings /// in turn. It can either store the results or deserialise them on the spot. /// </summary> /// <returns>true if the deserialiser was able to use the result or false otherwise</returns> protected override void ProcessResult(SparqlResult result) { #region Tracing #line hidden if (Logger.IsDebugEnabled) { Logger.Debug("Got Result {0}.", result.ToString()); } #line default #endregion if (IsSelectMember(SelectExpression)) { IncomingResults.Add(ExtractMemberAccess(result)); return; } if (originalType == null) { throw new LinqToRdfException("need ontology type to create"); } object t; IEnumerable <MemberInfo> props = GetPropertiesToPopulate(originalType, instanceType); if (originalType == instanceType) { #region not using a projection t = Activator.CreateInstance(instanceType); #region Tracing #line hidden if (Logger.IsDebugEnabled) { Logger.Debug("created new instance of {0}.", t.GetType().Name); } #line default #endregion AssignDataContext(t as OwlInstanceSupertype, DataContext); AssignInstanceUri(t as OwlInstanceSupertype, InstanceName, result); foreach (PropertyInfo pi in props) { if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition().Name.StartsWith("Entity")) { continue; } try { PopulateProperty(result, t, pi); } catch (ArgumentException ae) { #region Tracing #line hidden if (Logger.IsErrorEnabled) { Logger.ErrorEx("Unable to populate property " + pi.Name, ae); Logger.Error("continuing"); } #line default #endregion } catch (Exception e) { #region Tracing #line hidden if (Logger.IsErrorEnabled) { Logger.ErrorEx("Unable to populate property " + pi.Name, e); } #line default #endregion return; } } #endregion } else { #region using a projection var args = new List <object>(); foreach (PropertyInfo pi in props) { try { if (result.HasValue(pi.Name)) { if (result[pi.Name] != null) { string vVal = result[pi.Name].ToString(); vVal = RemoveEnclosingQuotesOnString(vVal, pi); if (IsXsdtEncoded(vVal)) { vVal = DecodeXsdtString(vVal); } args.Add(Convert.ChangeType(vVal, pi.PropertyType)); } } } catch (Exception e) { Console.WriteLine(e); return; } } t = Activator.CreateInstance(instanceType, args.ToArray()); #endregion } if (Distinct) { if (ObjectIsUniqueSoFar(t as OwlInstanceSupertype)) { IncomingResults.Add(t); } } else { IncomingResults.Add(t); } return; }
private static bool CompareSolutions(SparqlResult x, SparqlResult y, Dictionary<string,string> bnodeMap) { var boundVarsX = x.Variables.Where(v=>x.HasValue(v) && x.Value(v)!=null); var boundVarsY = y.Variables.Where(v=>y.HasValue(v) && y.Value(v)!=null); if (!boundVarsX.Any() && !boundVarsY.Any()) return true; if (x.Variables.Count().Equals(y.Variables.Count()) && x.Variables.All(xv=>y.Variables.Contains(xv))) { foreach (var xv in x.Variables) { var xb = x[xv]; var yb = y[xv]; if (!CompareNodes(xb, yb, bnodeMap)) return false; } return true; } return false; }
/// <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; } }
/// <summary> /// Internal method which actually parses the Result Set by traversing the RDF Graph appropriately /// </summary> /// <param name="context">Parser Context</param> private void Parse(SparqlRdfParserContext context) { try { context.Handler.StartResults(); //Create relevant Nodes context.Graph.NamespaceMap.AddNamespace("rdf", UriFactory.Create(NamespaceMapper.RDF)); context.Graph.NamespaceMap.AddNamespace("rs", UriFactory.Create(SparqlSpecsHelper.SparqlRdfResultsNamespace)); IUriNode rdfType = context.Graph.CreateUriNode("rdf:type"); IUriNode resultSetClass = context.Graph.CreateUriNode("rs:ResultSet"); IUriNode resultVariable = context.Graph.CreateUriNode("rs:resultVariable"); IUriNode solution = context.Graph.CreateUriNode("rs:solution"); IUriNode binding = context.Graph.CreateUriNode("rs:binding"); IUriNode value = context.Graph.CreateUriNode("rs:value"); IUriNode variable = context.Graph.CreateUriNode("rs:variable"); IUriNode boolean = context.Graph.CreateUriNode("rs:boolean"); //Try to get a ResultSet object Triple rset = context.Graph.Triples.WithPredicateObject(rdfType, resultSetClass).FirstOrDefault(); if (rset != null) { INode rsetID = rset.Subject; //Find the Variables the Result Set contains or the Boolean Value List <Triple> temp = context.Graph.Triples.WithSubjectPredicate(rsetID, boolean).ToList(); if (temp.Count > 0) { if (temp.Count > 1) { throw new RdfParseException("Result Set has more than one boolean result defined for it"); } Triple booleanResult = temp.First(); INode result = booleanResult.Object; if (result.NodeType == NodeType.Literal) { ILiteralNode lit = (ILiteralNode)result; if (lit.DataType != null) { if (lit.DataType.AbsoluteUri.Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean)) { bool b; if (Boolean.TryParse(lit.Value, out b)) { context.Handler.HandleBooleanResult(b); return; } else { throw new RdfParseException("Result Set has a boolean result which is a Literal typed as boolean but which does not contain a valid boolean value"); } } else { throw new RdfParseException("Result Set has a boolean result which is a Literal which is not boolean typed"); } } else { throw new RdfParseException("Result Set has a boolean result which is a Literal which is not typed as a boolean"); } } else { throw new RdfParseException("Result Set has a boolean result which is not a Literal Node"); } } else { //We're expected one/more variables temp = context.Graph.Triples.WithSubjectPredicate(rsetID, resultVariable).ToList(); if (temp.Count > 0) { foreach (Triple t in temp) { if (t.Object.NodeType == NodeType.Literal) { if (!context.Handler.HandleVariable(((ILiteralNode)t.Object).Value)) { ParserHelper.Stop(); } context.Variables.Add(((ILiteralNode)t.Object).Value); } else { throw new RdfParseException("Result Set has a result variable definition which is not a Literal Node"); } } } else { throw new RdfParseException("Result Set does not define any result variables or a boolean result"); } //Then we're expecting some Solutions temp = context.Graph.Triples.WithSubjectPredicate(rsetID, solution).ToList(); foreach (Triple slnTriple in temp) { //Each Solution has some Bindings INode slnID = slnTriple.Object; bool ok = false; SparqlResult r = new SparqlResult(); foreach (Triple bindingTriple in context.Graph.Triples.WithSubjectPredicate(slnID, binding)) { //Each Binding has a Variable and a Value ok = true; INode bindingID = bindingTriple.Object; String var = String.Empty; INode val = null; //Retrieve the Variable and the Bound Value foreach (Triple valueTriple in context.Graph.Triples.WithSubject(bindingID)) { if (valueTriple.Predicate.Equals(variable)) { if (!var.Equals(String.Empty)) { throw new RdfParseException("Result Set contains a Binding which refers to more than one Variable"); } if (valueTriple.Object.NodeType != NodeType.Literal) { throw new RdfParseException("Result Set contains a Binding which refers to a Variable but not by a Literal Node as required"); } var = ((ILiteralNode)valueTriple.Object).Value; } else if (valueTriple.Predicate.Equals(value)) { if (val != null) { throw new RdfParseException("Result Set contains a Binding which has more than one Value"); } val = valueTriple.Object; } } if (var.Equals(String.Empty) || val == null) { throw new RdfParseException("Result Set contains a Binding which doesn't contain both a Variable and a Value"); } //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!"); } r.SetValue(var, val); } if (!ok) { throw new RdfParseException("Result Set contains a Solution which has no Bindings"); } //Check that all Variables are bound for a given result binding nulls where appropriate foreach (String v in context.Variables) { if (!r.HasValue(v)) { r.SetValue(v, null); } } if (!context.Handler.HandleResult(r)) { ParserHelper.Stop(); } } } } else { throw new RdfParseException("No Result Set object is defined in the Graph"); } context.Handler.EndResults(true); } catch (RdfParsingTerminatedException) { context.Handler.EndResults(true); } catch { context.Handler.EndResults(false); throw; } }
/// <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 }
/// <summary> /// Internal method which actually parses the Result Set by traversing the RDF Graph appropriately /// </summary> /// <param name="context">Parser Context</param> private void Parse(SparqlRdfParserContext context) { try { context.Handler.StartResults(); //Create relevant Nodes context.Graph.NamespaceMap.AddNamespace("rdf", new Uri(NamespaceMapper.RDF)); context.Graph.NamespaceMap.AddNamespace("rs", new Uri(SparqlSpecsHelper.SparqlRdfResultsNamespace)); IUriNode rdfType = context.Graph.CreateUriNode("rdf:type"); IUriNode resultSetClass = context.Graph.CreateUriNode("rs:ResultSet"); IUriNode resultVariable = context.Graph.CreateUriNode("rs:resultVariable"); IUriNode solution = context.Graph.CreateUriNode("rs:solution"); IUriNode binding = context.Graph.CreateUriNode("rs:binding"); IUriNode value = context.Graph.CreateUriNode("rs:value"); IUriNode variable = context.Graph.CreateUriNode("rs:variable"); IUriNode boolean = context.Graph.CreateUriNode("rs:boolean"); //Try to get a ResultSet object Triple rset = context.Graph.Triples.WithPredicateObject(rdfType, resultSetClass).FirstOrDefault(); if (rset != null) { INode rsetID = rset.Subject; //Find the Variables the Result Set contains or the Boolean Value List<Triple> temp = context.Graph.Triples.WithSubjectPredicate(rsetID, boolean).ToList(); if (temp.Count > 0) { if (temp.Count > 1) throw new RdfParseException("Result Set has more than one boolean result defined for it"); Triple booleanResult = temp.First(); INode result = booleanResult.Object; if (result.NodeType == NodeType.Literal) { ILiteralNode lit = (ILiteralNode)result; if (lit.DataType != null) { if (lit.DataType.ToString().Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean)) { bool b; if (Boolean.TryParse(lit.Value, out b)) { context.Handler.HandleBooleanResult(b); return; } else { throw new RdfParseException("Result Set has a boolean result which is a Literal typed as boolean but which does not contain a valid boolean value"); } } else { throw new RdfParseException("Result Set has a boolean result which is a Literal which is not boolean typed"); } } else { throw new RdfParseException("Result Set has a boolean result which is a Literal which is not typed as a boolean"); } } else { throw new RdfParseException("Result Set has a boolean result which is not a Literal Node"); } } else { //We're expected one/more variables temp = context.Graph.Triples.WithSubjectPredicate(rsetID, resultVariable).ToList(); if (temp.Count > 0) { foreach (Triple t in temp) { if (t.Object.NodeType == NodeType.Literal) { if (!context.Handler.HandleVariable(((ILiteralNode)t.Object).Value)) ParserHelper.Stop(); context.Variables.Add(((ILiteralNode)t.Object).Value); } else { throw new RdfParseException("Result Set has a result variable definition which is not a Literal Node"); } } } else { throw new RdfParseException("Result Set does not define any result variables or a boolean result"); } //Then we're expecting some Solutions temp = context.Graph.Triples.WithSubjectPredicate(rsetID, solution).ToList(); foreach (Triple slnTriple in temp) { //Each Solution has some Bindings INode slnID = slnTriple.Object; bool ok = false; SparqlResult r = new SparqlResult(); foreach (Triple bindingTriple in context.Graph.Triples.WithSubjectPredicate(slnID, binding)) { //Each Binding has a Variable and a Value ok = true; INode bindingID = bindingTriple.Object; String var = String.Empty; INode val = null; //Retrieve the Variable and the Bound Value foreach (Triple valueTriple in context.Graph.Triples.WithSubject(bindingID)) { if (valueTriple.Predicate.Equals(variable)) { if (!var.Equals(String.Empty)) throw new RdfParseException("Result Set contains a Binding which refers to more than one Variable"); if (valueTriple.Object.NodeType != NodeType.Literal) throw new RdfParseException("Result Set contains a Binding which refers to a Variable but not by a Literal Node as required"); var = ((ILiteralNode)valueTriple.Object).Value; } else if (valueTriple.Predicate.Equals(value)) { if (val != null) throw new RdfParseException("Result Set contains a Binding which has more than one Value"); val = valueTriple.Object; } } if (var.Equals(String.Empty) || val == null) throw new RdfParseException("Result Set contains a Binding which doesn't contain both a Variable and a Value"); //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!"); } r.SetValue(var, val); } if (!ok) throw new RdfParseException("Result Set contains a Solution which has no Bindings"); //Check that all Variables are bound for a given result binding nulls where appropriate foreach (String v in context.Variables) { if (!r.HasValue(v)) { r.SetValue(v, null); } } if (!context.Handler.HandleResult(r)) ParserHelper.Stop(); } } } else { throw new RdfParseException("No Result Set object is defined in the Graph"); } context.Handler.EndResults(true); } catch (RdfParsingTerminatedException) { context.Handler.EndResults(true); } catch { context.Handler.EndResults(false); throw; } }