Ejemplo n.º 1
0
 /// <summary>
 /// Internal Helper method which parses the child element of a &lt;binding&gt; element into an <see cref="INode">INode</see>
 /// </summary>
 /// <param name="context">Parser Context</param>
 /// <returns></returns>
 private INode ParseValue(SparqlXmlParserContext context)
 {
     if (context.Input.Name.Equals("uri"))
     {
         return context.Handler.CreateUriNode(new Uri(context.Input.ReadElementContentAsString()));
     }
     else if (context.Input.Name.Equals("literal"))
     {
         if (context.Input.AttributeCount == 0)
         {
             //Literal with no Data Type/Language Specifier
             return context.Handler.CreateLiteralNode(HttpUtility.HtmlDecode(context.Input.ReadInnerXml()));
         }
         else if (context.Input.AttributeCount == 1)
         {
             context.Input.MoveToNextAttribute();
             if (context.Input.Name.Equals("xml:lang"))
             {
                 //Language is specified
                 String lang = context.Input.Value;
                 context.Input.MoveToContent();
                 return context.Handler.CreateLiteralNode(context.Input.ReadElementContentAsString(), lang);
             }
             else if (context.Input.Name.Equals("datatype"))
             {
                 //Data Type is specified
                 String dt = context.Input.Value;
                 context.Input.MoveToContent();
                 return context.Handler.CreateLiteralNode(context.Input.ReadElementContentAsString(), new Uri(dt));
             }
             else
             {
                 throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <literal> element has an unknown attribute '" + context.Input.Name + "'!");
             }
         }
         else
         {
             throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <literal> element has too many Attributes, only 1 of 'xml:lang' or 'datatype' may be specified!");
         }
     }
     else if (context.Input.Name.Equals("bnode"))
     {
         String bnodeID = context.Input.ReadElementContentAsString();
         if (bnodeID.StartsWith("_:"))
         {
             return context.Handler.CreateBlankNode(bnodeID.Substring(2));
         }
         else if (bnodeID.Contains("://"))
         {
             return context.Handler.CreateBlankNode(bnodeID.Substring(bnodeID.IndexOf("://") + 3));
         }
         else if (bnodeID.Contains(":"))
         {
             return context.Handler.CreateBlankNode(bnodeID.Substring(bnodeID.LastIndexOf(':') + 1));
         }
         else
         {
             return context.Handler.CreateBlankNode(bnodeID);
         }
     }
     else if (context.Input.Name.Equals("unbound"))
     {
         //HACK: This is a really ancient feature of the SPARQL Results XML format (from Working Draft in 2005) which we support to ensure compatability with old pre-standardisation SPARQL endpoints (like 3store based ones)
         context.Input.ReadInnerXml();
         return null;
     }
     else
     {
         throw new RdfParseException("Unable to Parse a SPARQL Result Set since a <binding> element contains an unexpected element <" + context.Input.Name + ">!");
     }
 }
Ejemplo n.º 2
0
        /// <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;
            }
        }