Exemple #1
0
        private void TryParseTriple(XmlReader reader, IRdfHandler handler, Uri graphUri)
        {
            //Verify Node Name
            if (!reader.Name.Equals("triple"))
            {
                throw Error("Unexpected Element <" + reader.Name + "> encountered, only an optional <id>/<uri> element followed by zero/more <triple> elements are permitted within a <graph> element", reader);
            }

            //Parse XML Nodes into RDF Nodes
            INode subj, pred, obj;

            subj = this.TryParseNode(reader, handler, TripleSegment.Subject);
            pred = this.TryParseNode(reader, handler, TripleSegment.Predicate);
            obj  = this.TryParseNode(reader, handler, TripleSegment.Object);

            if (reader.NodeType != XmlNodeType.EndElement)
            {
                throw Error("Unexpected element type " + reader.NodeType.ToString() + " encountered, expected the </triple> element", reader);
            }
            if (!reader.Name.Equals("triple"))
            {
                throw Error("Unexpected </" + reader.Name + "> encountered, expected a </triple> element", reader);
            }

            //Assert the resulting Triple
            if (!handler.HandleTriple(new Triple(subj, pred, obj, graphUri)))
            {
                ParserHelper.Stop();
            }
        }
Exemple #2
0
        private void TryParseTriple(IRdfHandler handler, IToken s, IToken p, IToken o, Uri graphUri)
        {
            INode subj, pred, obj;

            switch (s.TokenType)
            {
            case Token.BLANKNODEWITHID:
                subj = handler.CreateBlankNode(s.Value.Substring(2));
                break;

            case Token.URI:
                subj = ParserHelper.TryResolveUri(handler, s);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + s.GetType().ToString() + "' encountered, expected a Blank Node/URI as the Subject of a Triple", s);
            }

            switch (p.TokenType)
            {
            case Token.URI:
                pred = ParserHelper.TryResolveUri(handler, p);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + p.GetType().ToString() + "' encountered, expected a URI as the Predicate of a Triple", p);
            }

            switch (o.TokenType)
            {
            case Token.BLANKNODEWITHID:
                obj = handler.CreateBlankNode(o.Value.Substring(2));
                break;

            case Token.LITERAL:
                obj = handler.CreateLiteralNode(o.Value);
                break;

            case Token.LITERALWITHDT:
                String dtUri = ((LiteralWithDataTypeToken)o).DataType;
                obj = handler.CreateLiteralNode(o.Value, new Uri(dtUri.Substring(1, dtUri.Length - 2)));
                break;

            case Token.LITERALWITHLANG:
                obj = handler.CreateLiteralNode(o.Value, ((LiteralWithLanguageSpecifierToken)o).Language);
                break;

            case Token.URI:
                obj = ParserHelper.TryResolveUri(handler, o);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + o.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Object of a Triple", o);
            }

            if (!handler.HandleTriple(new Triple(subj, pred, obj, graphUri)))
            {
                ParserHelper.Stop();
            }
        }
        private void TryParseHeaderRow(TokenisingResultParserContext context)
        {
            IToken next = context.Tokens.Peek();
            bool   allowEOL = true, expectComma = false;

            while (true)
            {
                next = context.Tokens.Dequeue();
                switch (next.TokenType)
                {
                case Token.EOL:
                    if (allowEOL)
                    {
                        break;
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected End of Line, expected a Variable", next);
                    }

                case Token.PLAINLITERAL:
                case Token.LITERAL:
                    if (expectComma)
                    {
                        throw ParserHelper.Error("Unexpected Variable, expected a comma between each Variable", next);
                    }
                    context.Variables.Add(next.Value);
                    if (!context.Handler.HandleVariable(next.Value))
                    {
                        ParserHelper.Stop();
                    }
                    allowEOL    = true;
                    expectComma = true;
                    break;

                case Token.COMMA:
                    expectComma = false;
                    allowEOL    = false;
                    break;

                case Token.EOF:
                    if (!allowEOL)
                    {
                        throw ParserHelper.Error("Unexpected EOF, expected another Variable for the Header 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;
                }
            }
        }
Exemple #4
0
        private void TryParseDirective(TriGParserContext context)
        {
            //See what type of directive it is
            IToken directive = context.Tokens.Dequeue();

            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                //Base Directives Invalid in TriG
                throw ParserHelper.Error("The Base Directive is not a valid in TriG", directive);
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                //Prefix Directive
                IToken prefix = context.Tokens.Dequeue();
                if (prefix.TokenType == Token.PREFIX)
                {
                    IToken uri = context.Tokens.Dequeue();
                    if (uri.TokenType == Token.URI)
                    {
                        //Ensure the Uri is absolute
                        try
                        {
                            Uri    u   = new Uri(uri.Value, UriKind.Absolute);
                            String pre = (prefix.Value.Equals(":")) ? String.Empty : prefix.Value.Substring(0, prefix.Value.Length - 1);
                            context.Namespaces.AddNamespace(pre, u);
                            if (!context.Handler.HandleNamespace(pre, u))
                            {
                                ParserHelper.Stop();
                            }

                            //Expect a DOT to Terminate
                            IToken dot = context.Tokens.Dequeue();
                            if (dot.TokenType != Token.DOT)
                            {
                                throw ParserHelper.Error("Unexpected Token '" + dot.GetType().ToString() + "' encountered, expected a Dot (Line Terminator) Token to terminate a Prefix Directive", dot);
                            }
                        }
                        catch (UriFormatException)
                        {
                            throw ParserHelper.Error("The URI '" + uri.Value + "' given for the prefix '" + prefix.Value + "' is not a valid Absolute URI", uri);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a URI Token after a Prefix Token", uri);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a Prefix Token after a Prefix Directive Token", prefix);
                }
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix Directive Token", directive);
            }
        }
        private void TryParseTriple(TokenisingParserContext context)
        {
            // Get the Subject, Predicate and Object
            INode subj = TryParseSubject(context);
            INode pred = TryParsePredicate(context);
            INode obj  = TryParseObject(context);

            // Ensure we're terminated by a DOT
            TryParseLineTerminator(context);

            // Assert the Triple
            if (!context.Handler.HandleTriple(new Triple(subj, pred, obj)))
            {
                ParserHelper.Stop();
            }
        }
Exemple #6
0
        /// <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");
            }
        }
Exemple #7
0
 /// <summary>
 /// Parser method which parses the 'vars' property of the Header Object
 /// </summary>
 private void ParseVariables(SparqlJsonParserContext context)
 {
     //Can we read the Variable Array
     if (context.Input.Read())
     {
         if (context.Input.TokenType == JsonToken.StartArray)
         {
             context.Input.Read();
             while (context.Input.TokenType != JsonToken.EndArray)
             {
                 if (context.Input.TokenType == JsonToken.String)
                 {
                     //Add to Variables
                     if (!context.Handler.HandleVariable(context.Input.Value.ToString()))
                     {
                         ParserHelper.Stop();
                     }
                     context.Variables.Add(context.Input.Value.ToString());
                 }
                 else
                 {
                     throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' encountered, expected a String giving the name of a Variable for the Result Set");
                 }
                 context.Input.Read();
             }
         }
         else
         {
             throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' encountered, expected the Start of an Array giving the list of Variables for the 'vars' property of the Header Object of the JSON Result Set");
         }
     }
     else
     {
         throw new RdfParseException("Unexpected End of Input while trying to parse the 'vars' property of the Header Object of the JSON Result Set");
     }
 }
Exemple #8
0
        /// <summary>
        /// Parser method which parses Json Objects reprsenting Object Nodes
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="subj">Subject of Triples which comes from the Great-Grandparent Json Object</param>
        /// <param name="pred">Predicate of Triples which comes form the Grandparent Json Object</param>
        private void ParseObject(JsonParserContext context, INode subj, INode pred)
        {
            String token, nodeValue, nodeType, nodeLang, nodeDatatype;

            nodeValue = nodeType = nodeLang = nodeDatatype = null;

            PositionInfo startPos = context.CurrentPosition;

            if (context.Input.Read())
            {
                if (context.Input.TokenType == JsonToken.StartObject)
                {
                    context.Input.Read();
                    while (context.Input.TokenType != JsonToken.EndObject)
                    {
                        if (context.Input.TokenType == JsonToken.PropertyName)
                        {
                            token = context.Input.Value.ToString().ToLower();

                            //Check that we get a Property Value as a String
                            context.Input.Read();
                            if (context.Input.TokenType != JsonToken.String)
                            {
                                throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' encountered, expected a Property Value describing one of the properties of an Object Node", startPos);
                            }

                            //Extract the Information from the Object
                            if (token.Equals("value"))
                            {
                                nodeValue = context.Input.Value.ToString();
                            }
                            else if (token.Equals("type"))
                            {
                                nodeType = context.Input.Value.ToString().ToLower();
                            }
                            else if (token.Equals("lang") || token.Equals("xml:lang"))
                            {
                                if (nodeLang == null && nodeDatatype == null)
                                {
                                    nodeLang = context.Input.Value.ToString();
                                }
                                else
                                {
                                    throw Error(context, "Unexpected Language Property specified for an Object Node where a Language or Datatype has already been specified", startPos);
                                }
                            }
                            else if (token.Equals("datatype"))
                            {
                                if (nodeDatatype == null && nodeLang == null)
                                {
                                    nodeDatatype = context.Input.Value.ToString();
                                }
                                else
                                {
                                    throw Error(context, "Unexpected Datatype Property specified for an Object Node where a Language or Datatype has already been specified", startPos);
                                }
                            }
                            else
                            {
                                throw Error(context, "Unexpected Property '" + token + "' specified for an Object Node, only 'value', 'type', 'lang' and 'datatype' are valid properties", startPos);
                            }
                        }
                        else
                        {
                            throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' encountered, expected a Property Name describing one of the properties of an Object Node", startPos);
                        }

                        context.Input.Read();
                    }

                    //Validate the Information
                    if (nodeType == null)
                    {
                        throw Error(context, "Cannot parse an Object Node from the JSON where no 'type' property was specified in the JSON Object representing the Node", startPos);
                    }
                    if (nodeValue == null)
                    {
                        throw Error(context, "Cannot parse an Object Node from the JSON where no 'value' property was specified in the JSON Object representing the Node", startPos);
                    }

                    //Turn this information into a Node
                    INode obj;
                    if (nodeType.Equals("uri"))
                    {
                        obj = context.Handler.CreateUriNode(new Uri(nodeValue));
                    }
                    else if (nodeType.Equals("bnode"))
                    {
                        obj = context.Handler.CreateBlankNode(nodeValue.Substring(nodeValue.IndexOf(':') + 1));
                    }
                    else if (nodeType.Equals("literal"))
                    {
                        if (nodeLang != null)
                        {
                            obj = context.Handler.CreateLiteralNode(nodeValue, nodeLang);
                        }
                        else if (nodeDatatype != null)
                        {
                            obj = context.Handler.CreateLiteralNode(nodeValue, new Uri(nodeDatatype));
                        }
                        else
                        {
                            obj = context.Handler.CreateLiteralNode(nodeValue);
                        }
                    }
                    else
                    {
                        throw Error(context, "Cannot parse an Object Node from the JSON where the 'type' property is not set to one of the permitted values 'uri', 'bnode' or 'literal' in the JSON Object representing the Node", startPos);
                    }

                    //Assert as a Triple
                    if (!context.Handler.HandleTriple(new Triple(subj, pred, obj)))
                    {
                        ParserHelper.Stop();
                    }
                }
            }
            else
            {
                throw Error(context, "Unexpected End of Input while trying to parse an Object Node from the JSON", startPos);
            }
        }
Exemple #9
0
        /// <summary>
        /// Parser method which parses the 'vars' property of the Header Object
        /// </summary>
        private void ParseVariables(SparqlJsonParserContext context, bool bodySeen)
        {
            //Can we read the Variable Array
            if (context.Input.Read())
            {
                if (context.Input.TokenType == JsonToken.StartArray)
                {
                    context.Input.Read();
                    List <String> vars = new List <string>();
                    while (context.Input.TokenType != JsonToken.EndArray)
                    {
                        if (context.Input.TokenType == JsonToken.String)
                        {
                            //Add to Variables
                            if (!context.Handler.HandleVariable(context.Input.Value.ToString()))
                            {
                                ParserHelper.Stop();
                            }
                            if (bodySeen)
                            {
                                // We've already seen the body in which case store locally for now
                                vars.Add(context.Input.Value.ToString());
                            }
                            else
                            {
                                // We're seeing the header first so just add to list of variables
                                context.Variables.Add(context.Input.Value.ToString());
                            }
                        }
                        else
                        {
                            throw Error(context, "Unexpected Token '" + context.Input.TokenType + "' with value '" + context.Input.Value + "' encountered, expected a String giving the name of a Variable for the Result Set");
                        }
                        context.Input.Read();
                    }

                    // If we've already seen the body check for variable conflicts
                    if (!bodySeen)
                    {
                        return;
                    }
                    foreach (String var in context.Variables)
                    {
                        if (!vars.Contains(var))
                        {
                            throw new RdfParseException("Unable to Parse a SPARQL Result Set since a Binding Object binds a value to the variable '" + var + "' which is not defined in the Header Object in the value for the 'vars' property!");
                        }
                    }
                    foreach (String var in context.Variables)
                    {
                        if (!context.Handler.HandleVariable(var))
                        {
                            ParserHelper.Stop();
                        }
                    }
                }
                else
                {
                    throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' with value '" + context.Input.Value + "' encountered, expected the Start of an Array giving the list of Variables for the 'vars' property of the Header Object of the JSON Result Set");
                }
            }
            else
            {
                throw new RdfParseException("Unexpected End of Input while trying to parse the 'vars' property of the Header Object of the JSON Result Set");
            }
        }
Exemple #10
0
        /// <summary>
        /// Parser method which parses Json Objects representing Triples
        /// </summary>
        /// <param name="context">Parser Context</param>
        private void ParseTriples(JsonParserContext context)
        {
            PositionInfo startPos = context.CurrentPosition;

            do
            {
                if (context.Input.TokenType == JsonToken.StartObject)
                {
                    INode s, p, o;
                    s = p = o = null;
                    INode         temp;
                    TripleSegment segment;

                    //Expect 3 Nodes in a Triple
                    for (int i = 0; i < 3; i++)
                    {
                        temp = this.TryParseNode(context, out segment);
                        switch (segment)
                        {
                        case TripleSegment.Object:
                            if (o == null)
                            {
                                o = temp;
                            }
                            else
                            {
                                throw Error(context, "Duplicate object property encountered");
                            }
                            break;

                        case TripleSegment.Predicate:
                            if (p == null)
                            {
                                p = temp;
                            }
                            else
                            {
                                throw Error(context, "Duplicate predicate property encountered");
                            }
                            break;

                        case TripleSegment.Subject:
                            if (s == null)
                            {
                                s = temp;
                            }
                            else
                            {
                                throw Error(context, "Duplicate Subject property encountered");
                            }
                            break;
                        }
                    }

                    if (!context.Handler.HandleTriple((new Triple(s, p, o))))
                    {
                        ParserHelper.Stop();
                    }
                }
                else
                {
                    throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + "' encountered, start of a JSON Object for a Triple was expected");
                }

                //Then expect the end of the Object
                if (context.Input.Read())
                {
                    if (context.Input.TokenType != JsonToken.EndObject)
                    {
                        throw Error(context, "Unexpected Token '" + context.Input.TokenType.ToString() + " encountered, expected the end of the JSON Object for a Triple");
                    }
                }
                else
                {
                    throw Error(context, "Unexpected End of Input while trying to parse Triples from JSON, end of a Triple Object was expected", startPos);
                }

                //Then expect an End Array/Start Object
                if (!context.Input.Read())
                {
                    throw Error(context, "Unexpected End of Input while trying to parse Triples from JSON, end of JSON array or start of a JSON Object was expected", startPos);
                }
            } while (context.Input.TokenType == JsonToken.StartObject);
        }
Exemple #11
0
        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();
            }
        }
Exemple #12
0
        private void TryParseTriple(XmlNode tripleEl, IRdfHandler handler, Uri graphUri)
        {
            //Verify Node Name
            if (!tripleEl.Name.Equals("triple"))
            {
                throw new RdfParseException("Unexpected Element <" + tripleEl.Name + "> encountered, only an optional <uri> element followed by zero/more <triple> elements are permitted within a <graph> element");
            }
            //Verify number of Child Nodes
            if (!tripleEl.HasChildNodes)
            {
                throw new RdfParseException("<triple> element has no child nodes - 3 child nodes are expected");
            }
            if (tripleEl.ChildNodes.Count < 3)
            {
                throw new RdfParseException("<triple> element has too few child nodes (" + tripleEl.ChildNodes.Count + ") - 3 child nodes are expected");
            }
            if (tripleEl.ChildNodes.Count > 3)
            {
                throw new RdfParseException("<triple> element has too many child nodes (" + tripleEl.ChildNodes.Count + ") - 3 child nodes are expected");
            }

            //Get the 3 Child Nodes
            XmlNode subjEl, predEl, objEl;

            subjEl = tripleEl.ChildNodes[0];
            predEl = tripleEl.ChildNodes[1];
            objEl  = tripleEl.ChildNodes[2];

            //Parse XML Nodes into RDF Nodes
            INode subj, pred, obj;

            if (subjEl.Name.Equals("uri"))
            {
                subj = handler.CreateUriNode(UriFactory.Create(subjEl.InnerText));
            }
            else if (subjEl.Name.Equals("id"))
            {
                subj = handler.CreateBlankNode(subjEl.InnerText);
            }
            else
            {
                throw Error("Unexpected element <" + subjEl.Name + "> encountered, expected a <id>/<uri> element as the Subject of a Triple", subjEl);
            }

            if (predEl.Name.Equals("uri"))
            {
                pred = handler.CreateUriNode(UriFactory.Create(predEl.InnerText));
            }
            else
            {
                throw Error("Unexpected element <" + predEl.Name + "> encountered, expected a <uri> element as the Predicate of a Triple", subjEl);
            }

            if (objEl.Name.Equals("uri"))
            {
                obj = handler.CreateUriNode(UriFactory.Create(objEl.InnerText));
            }
            else if (objEl.Name.Equals("id"))
            {
                obj = handler.CreateBlankNode(objEl.InnerText);
            }
            else if (objEl.Name.Equals("plainLiteral"))
            {
                if (objEl.Attributes.GetNamedItem("xml:lang") != null)
                {
                    obj = handler.CreateLiteralNode(objEl.InnerText, objEl.Attributes["xml:lang"].Value);
                }
                else
                {
                    obj = handler.CreateLiteralNode(objEl.InnerText);
                }
            }
            else if (objEl.Name.Equals("typedLiteral"))
            {
                if (objEl.Attributes.GetNamedItem("datatype") != null)
                {
                    Uri dtUri = UriFactory.Create(objEl.Attributes["datatype"].Value);
                    if (objEl.FirstChild.NodeType == XmlNodeType.Text)
                    {
                        obj = handler.CreateLiteralNode(objEl.InnerText, dtUri);
                    }
                    else if (objEl.FirstChild.NodeType == XmlNodeType.CDATA)
                    {
                        obj = handler.CreateLiteralNode(objEl.FirstChild.InnerXml, dtUri);
                    }
                    else
                    {
                        obj = handler.CreateLiteralNode(objEl.InnerText, dtUri);
                    }
                }
                else
                {
                    throw Error("<typedLiteral> element does not have the required datatype attribute", objEl);
                }
            }
            else
            {
                throw Error("Unexpected element <" + objEl.Name + "> encountered, expected a <id>/<uri>/<plainLiteral>/<typedLiteral> element as the Object of a Triple", subjEl);
            }

            //Assert the resulting Triple
            if (!handler.HandleTriple(new Triple(subj, pred, obj, graphUri)))
            {
                ParserHelper.Stop();
            }
            ;
        }
Exemple #13
0
        /// <summary>
        /// Internal Method which performs multi-threaded reading of data
        /// </summary>
        private void LoadGraphs(FolderStoreParserContext context)
        {
            //Create the relevant Parser
            IRdfReader parser;

            switch (context.Format)
            {
            case FolderStoreFormat.Turtle:
                parser = new TurtleParser();
                break;

            case FolderStoreFormat.Notation3:
                parser = new Notation3Parser();
                break;

            case FolderStoreFormat.RdfXml:
                parser = new RdfXmlParser();
                break;

            default:
                parser = new TurtleParser();
                break;
            }

            try
            {
                String file = context.GetNextFilename();
                while (file != null)
                {
                    //Read from Disk
                    Graph  g          = new Graph();
                    String sourceFile = Path.Combine(context.Folder, file);
                    parser.Load(g, sourceFile);

                    //Add to Graph Collection
                    foreach (Triple t in g.Triples)
                    {
                        if (context.Terminated)
                        {
                            break;
                        }
                        if (!context.Handler.HandleTriple(t))
                        {
                            ParserHelper.Stop();
                        }
                    }

                    if (context.Terminated)
                    {
                        break;
                    }

                    //Get the Next Filename
                    file = context.GetNextFilename();
                }
            }
            catch (ThreadAbortException)
            {
                //We've been terminated, don't do anything
#if !SILVERLIGHT
                Thread.ResetAbort();
#endif
            }
            catch (RdfParsingTerminatedException)
            {
                context.Terminated = true;
                context.ClearFilenames();
            }
            catch (Exception ex)
            {
                throw new RdfStorageException("Error in Threaded Reader in Thread ID " + Thread.CurrentThread.ManagedThreadId, ex);
            }
        }
        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();
            }
        }
Exemple #15
0
        private void TryParseObjectList(TriGParserContext context, Uri graphUri, INode subj, INode pred)
        {
            bool ok = false;

            do
            {
                //After the first run through we'll need to discard commas here
                if (ok)
                {
                    context.Tokens.Dequeue();
                }

                //Try to get the Object
                IToken obj = context.Tokens.Dequeue();
                IToken next;
                INode  objNode;

                switch (obj.TokenType)
                {
                case Token.COMMENT:
                    //Discard and Continue
                    ok = false;
                    continue;

                case Token.QNAME:
                case Token.URI:
                    objNode = ParserHelper.TryResolveUri(context, obj);
                    break;

                case Token.LITERAL:
                case Token.LONGLITERAL:
                    //Literals

                    //See whether we get a Language Specifier/Data Type next
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.LANGSPEC)
                    {
                        //Literal with Language Specifier
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateLiteralNode(obj.Value, next.Value);
                    }
                    else if (next.TokenType == Token.HATHAT)
                    {
                        //Literal with DataType
                        context.Tokens.Dequeue();
                        //Now expect a QName/Uri Token
                        next = context.Tokens.Dequeue();
                        if (next.TokenType == Token.QNAME || next.TokenType == Token.URI)
                        {
                            Uri dt = UriFactory.Create(Tools.ResolveUriOrQName(next, context.Namespaces, context.BaseUri));
                            objNode = context.Handler.CreateLiteralNode(obj.Value, dt);
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName Token to specify a Data Type after a ^^ Token", next);
                        }
                    }
                    else
                    {
                        //Just a string literal
                        objNode = context.Handler.CreateLiteralNode(obj.Value);
                    }
                    break;

                case Token.PLAINLITERAL:
                    //Plain Literals
                    Uri plt = TurtleSpecsHelper.InferPlainLiteralType((PlainLiteralToken)obj, TurtleSyntax.Original);
                    objNode = context.Handler.CreateLiteralNode(obj.Value, plt);
                    break;

                case Token.BLANKNODEWITHID:
                    //Blank Node with ID
                    objNode = context.Handler.CreateBlankNode(obj.Value.Substring(2));
                    break;

                case Token.LEFTSQBRACKET:
                    //Blank Node
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        //Anonymous Blank Node
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        //Blank Node Collection
                        objNode = context.Handler.CreateBlankNode();

                        //Do an extra call to TryParsePredicateObjectList to parse the Blank Node Collection
                        this.TryParsePredicateObjectList(context, graphUri, objNode);
                    }
                    break;

                case Token.RIGHTSQBRACKET:
                    //End of Blank Node Collection
                    if (!ok)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered before an Object list of a Blank Node Collection was parsed", obj);
                    }
                    return;

                case Token.LEFTBRACKET:
                    //Collection

                    //Check whether an Empty Collection
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        //Empty Collection
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        //Collection
                        objNode = context.Handler.CreateBlankNode();
                        this.TryParseCollection(context, graphUri, objNode);
                    }
                    break;

                case Token.EOF:
                    throw ParserHelper.Error("Unexpected End of File while trying to parse Object List", obj);

                case Token.DOT:
                case Token.RIGHTCURLYBRACKET:
                case Token.SEMICOLON:
                    if (!ok)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered before an Object list was parsed", obj);
                    }
                    return;

                default:
                    //Unexpected Token
                    throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered, expected a URI/QName/Blank Node as the Object of a Triple", obj);
                }

                ok = true;

                if (!context.Handler.HandleTriple(new Triple(subj, pred, objNode, graphUri)))
                {
                    ParserHelper.Stop();
                }
            } while (context.Tokens.Peek().TokenType == Token.COMMA); //Expect a comma if we are to continue
        }
Exemple #16
0
        private void TryParseCollection(TriGParserContext context, Uri graphUri, INode subj)
        {
            //Create the Nodes we need
            IUriNode rdfFirst, rdfRest, rdfNil;

            rdfFirst = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListFirst));
            rdfRest  = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListRest));
            rdfNil   = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));

            IToken next;
            INode  item, temp;

            item = null;
            do
            {
                next = context.Tokens.Dequeue();

                //Create a Node for this Token
                switch (next.TokenType)
                {
                case Token.COMMENT:
                    //Discard and continue;
                    continue;

                case Token.QNAME:
                case Token.URI:
                    item = ParserHelper.TryResolveUri(context, next);
                    break;

                case Token.LITERAL:
                case Token.LONGLITERAL:

                    break;

                case Token.PLAINLITERAL:
                    Uri plt = TurtleSpecsHelper.InferPlainLiteralType((PlainLiteralToken)next, TurtleSyntax.Original);
                    item = context.Handler.CreateLiteralNode(next.Value, plt);
                    break;

                case Token.LEFTSQBRACKET:
                    //Check whether an anonymous Blank Node or a Blank Node Collection
                    item = context.Handler.CreateBlankNode();

                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        //Anonymous Blank Node
                        context.Tokens.Dequeue();
                    }
                    else
                    {
                        //Blank Node Collection
                        this.TryParsePredicateObjectList(context, graphUri, item);
                    }
                    break;

                case Token.LEFTBRACKET:
                    //Check whether an Empty Collection
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        //Empty Collection
                        context.Tokens.Dequeue();
                        item = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        //Collection
                        item = context.Handler.CreateBlankNode();
                        this.TryParseCollection(context, graphUri, item);
                    }
                    break;

                case Token.EOF:
                    throw ParserHelper.Error("Unexpected End of File while trying to parse a Collection", next);

                default:
                    //Unexpected Token
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName/Literal/Blank Node as an item in a Collection", next);
                }

                //Create the subj rdf:first item Triple
                if (!context.Handler.HandleTriple((new Triple(subj, rdfFirst, item, graphUri))))
                {
                    ParserHelper.Stop();
                }

                //Create the rdf:rest Triple
                if (context.Tokens.Peek().TokenType == Token.RIGHTBRACKET)
                {
                    //End of Collection
                    context.Tokens.Dequeue();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil, graphUri)))
                    {
                        ParserHelper.Stop();
                    }
                    return;
                }
                else
                {
                    //Continuing Collection
                    temp = context.Handler.CreateBlankNode();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, temp, graphUri)))
                    {
                        ParserHelper.Stop();
                    }
                    subj = temp;
                }
            } while (true);
        }
Exemple #17
0
        /// <summary>
        /// Tries to parse Base/Prefix declarations
        /// </summary>
        /// <param name="context">Parse Context</param>
        private void TryParseDirective(TokenisingParserContext context)
        {
            if (context.TraceParsing)
            {
                Console.WriteLine("Attempting to parse a Base/Prefix Declaration");
            }

            //If we've been called an AT token has been encountered which we can discard
            context.Tokens.Dequeue();

            //Then we expect either a Base Directive/Prefix Directive
            IToken directive = context.Tokens.Dequeue();

            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                //Then expect a Uri for the Base Uri
                IToken u = context.Tokens.Dequeue();
                if (u.TokenType == Token.URI)
                {
                    //Set the Base Uri resolving against the current Base if any
                    try
                    {
                        Uri baseUri = new Uri(Tools.ResolveUri(u.Value, context.BaseUri.ToSafeString()));
                        context.BaseUri = baseUri;
                        if (!context.Handler.HandleBaseUri(baseUri))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    catch (RdfException rdfEx)
                    {
                        throw new RdfParseException("Unable to set the Base URI to '" + u.Value + "' due to the following error:\n" + rdfEx.Message, u, rdfEx);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + u.GetType().ToString() + "' encountered, expected a URI after a Base Directive", u);
                }
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                //Expect a Prefix then a Uri
                IToken pre = context.Tokens.Dequeue();
                if (pre.TokenType == Token.PREFIX)
                {
                    IToken ns = context.Tokens.Dequeue();
                    if (ns.TokenType == Token.URI)
                    {
                        //Register a Namespace resolving the Namespace Uri against the Base Uri
                        try
                        {
                            Uri    nsUri    = new Uri(Tools.ResolveUri(ns.Value, context.BaseUri.ToSafeString()));
                            String nsPrefix = (pre.Value.Length > 1) ? pre.Value.Substring(0, pre.Value.Length - 1) : String.Empty;
                            context.Namespaces.AddNamespace(nsPrefix, nsUri);
                            if (!context.Handler.HandleNamespace(nsPrefix, nsUri))
                            {
                                ParserHelper.Stop();
                            }
                        }
                        catch (RdfException rdfEx)
                        {
                            throw new RdfParseException("Unable to resolve the Namespace URI '" + ns.Value + "' due to the following error:\n" + rdfEx.Message, ns, rdfEx);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + ns.GetType().ToString() + "' encountered, expected a URI after a Prefix Directive", pre);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + pre.GetType().ToString() + "' encountered, expected a Prefix after a Prefix Directive", pre);
                }
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix Directive after an @ symbol", directive);
            }

            //All declarations are terminated with a Dot
            IToken terminator = context.Tokens.Dequeue();

            if (terminator.TokenType != Token.DOT)
            {
                throw ParserHelper.Error("Unexpected Token '" + terminator.GetType().ToString() + "' encountered, expected a Dot Line Terminator to terminate a Prefix/Base Directive", terminator);
            }
        }
Exemple #18
0
        /// <summary>
        /// Tries to parse directives
        /// </summary>
        /// <param name="context"></param>
        /// <param name="directive"></param>
        /// <remarks>
        /// This overload is needed because in some cases we may dequeue a token before we know it is a directive
        /// </remarks>
        private void TryParseDirective(TriGParserContext context, IToken directive)
        {
            //See what type of directive it is
            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                IToken baseUri = context.Tokens.Dequeue();
                if (baseUri.TokenType == Token.URI)
                {
                    try
                    {
                        Uri newBase = new Uri(Tools.ResolveUri(baseUri.Value, context.BaseUri.ToSafeString()));
                        context.BaseUri = newBase;
                        this.RaiseWarning("The @base directive is not valid in all versions of the TriG specification, your data may not be compatible with some older tools which do not support this version of TriG");
                        if (!context.Handler.HandleBaseUri(newBase))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    catch (UriFormatException)
                    {
                        throw ParserHelper.Error("The URI '" + baseUri.Value + "' given for the Base URI  is not a valid URI", baseUri);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + baseUri.GetType().ToString() + "' encountered, expected a URI Token after a @base directive", baseUri);
                }
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                //Prefix Directive
                IToken prefix = context.Tokens.Dequeue();
                if (prefix.TokenType == Token.PREFIX)
                {
                    IToken uri = context.Tokens.Dequeue();
                    if (uri.TokenType == Token.URI)
                    {
                        //Ensure the Uri is absolute
                        try
                        {
                            Uri    u   = new Uri(Tools.ResolveUri(uri.Value, context.BaseUri.ToSafeString()));
                            String pre = (prefix.Value.Equals(":")) ? String.Empty : prefix.Value.Substring(0, prefix.Value.Length - 1);
                            context.Namespaces.AddNamespace(pre, u);
                            if (!context.Handler.HandleNamespace(pre, u))
                            {
                                ParserHelper.Stop();
                            }
                        }
                        catch (UriFormatException)
                        {
                            throw ParserHelper.Error("The URI '" + uri.Value + "' given for the prefix '" + prefix.Value + "' is not a valid URI", uri);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a URI Token after a Prefix Token", uri);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a Prefix Token after a Prefix Directive Token", prefix);
                }
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix Directive Token", directive);
            }

            //Expect a DOT to Terminate
            IToken dot = context.Tokens.Dequeue();

            if (dot.TokenType != Token.DOT)
            {
                throw ParserHelper.Error("Unexpected Token '" + dot.GetType().ToString() + "' encountered, expected a Dot (Line Terminator) Token to terminate a Base/Prefix Directive", dot);
            }
        }
        /// <summary>
        /// Tries to parse Collections.
        /// </summary>
        /// <param name="context">Parser Context.</param>
        /// <param name="firstSubj">Blank Node which is the head of the collection.</param>
        private void TryParseCollection(TurtleParserContext context, INode firstSubj)
        {
            // The opening bracket of the collection will already have been discarded when we get called
            IToken next;
            INode  subj = firstSubj;
            INode  obj = null, nextSubj;
            INode  rdfFirst = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListFirst));
            INode  rdfRest  = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListRest));
            INode  rdfNil   = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));

            do
            {
                next = context.Tokens.Dequeue();

                if (context.TraceParsing)
                {
                    Console.WriteLine("Trying to parse a Collection item from Token '" + next.GetType().ToString() + "'");
                }

                switch (next.TokenType)
                {
                case Token.BLANKNODE:
                    obj = context.Handler.CreateBlankNode();
                    break;

                case Token.BLANKNODEWITHID:
                    obj = context.Handler.CreateBlankNode(next.Value.Substring(2));
                    break;

                case Token.COMMENT:
                    // Discard and continue
                    continue;

                case Token.LEFTBRACKET:
                    // Start of a collection so create a new Blank Node to be it's first subject
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        // Empty Collection => rdf:nil
                        context.Tokens.Dequeue();
                        obj = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        obj = context.Handler.CreateBlankNode();
                        TryParseCollection(context, obj);
                    }
                    break;

                case Token.LEFTSQBRACKET:
                    // Allowed Blank Node Collections as part of a Collection
                    IToken temp = context.Tokens.Peek();
                    if (temp.TokenType == Token.RIGHTSQBRACKET)
                    {
                        // Anonymous Blank Node
                        context.Tokens.Dequeue();
                        obj = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        // Blank Node Collection
                        obj = context.Handler.CreateBlankNode();
                        TryParsePredicateObjectList(context, obj, true);
                    }
                    break;

                case Token.LITERAL:
                case Token.LITERALWITHDT:
                case Token.LITERALWITHLANG:
                case Token.LONGLITERAL:
                case Token.PLAINLITERAL:
                    obj = TryParseLiteral(context, next);
                    break;

                case Token.QNAME:
                case Token.URI:
                    obj = ParserHelper.TryResolveUri(context, next, false, context.QNameUnescapeFunction);
                    break;

                case Token.RIGHTBRACKET:
                    // We might terminate here if someone put a comment before the end of the Collection
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfFirst, obj)))
                    {
                        ParserHelper.Stop();
                    }
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil)))
                    {
                        ParserHelper.Stop();
                    }
                    return;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Collection", next);
                }

                // Assert the relevant Triples
                if (!context.Handler.HandleTriple(new Triple(subj, rdfFirst, obj)))
                {
                    ParserHelper.Stop();
                }
                if (context.Tokens.Peek().TokenType == Token.RIGHTBRACKET)
                {
                    // End of the Collection
                    context.Tokens.Dequeue();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil)))
                    {
                        ParserHelper.Stop();
                    }
                    return;
                }
                else
                {
                    // More stuff in the collection
                    nextSubj = context.Handler.CreateBlankNode();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, nextSubj)))
                    {
                        ParserHelper.Stop();
                    }
                    subj = nextSubj;
                }
            } while (true);
        }
        /// <summary>
        /// Tries to parse Object lists.
        /// </summary>
        /// <param name="context">Parse Context.</param>
        /// <param name="subj">Subject of the Triples.</param>
        /// <param name="pred">Predicate of the Triples.</param>
        /// <param name="bnodeList">Whether this is a Blank Node Object list.</param>
        private void TryParseObjectList(TurtleParserContext context, INode subj, INode pred, bool bnodeList)
        {
            IToken objToken, next;
            INode  obj = null;

            do
            {
                objToken = context.Tokens.Dequeue();

                if (context.TraceParsing)
                {
                    Console.WriteLine("Attempting to parse an Object List from the Object Token '" + objToken.GetType().ToString() + "'");
                }

                switch (objToken.TokenType)
                {
                case Token.BLANKNODE:
                    obj = context.Handler.CreateBlankNode();
                    break;

                case Token.BLANKNODEWITHID:
                    obj = context.Handler.CreateBlankNode(objToken.Value.Substring(2));
                    break;

                case Token.COMMA:
                    // Discard and continue - set object to null so we know we're expected to complete a triple
                    if (obj != null)
                    {
                        obj = null;
                        continue;
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Comma Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                    }

                case Token.COMMENT:
                    // Discard and ignore
                    continue;

                case Token.DOT:
                    if (obj != null)
                    {
                        // OK to return if we've seen a valid Triple
                        return;
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Dot Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                    }

                case Token.LEFTBRACKET:
                    // Start of a collection so create a new Blank Node to be it's first subject
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        // Empty Collection => rdf:nil
                        context.Tokens.Dequeue();
                        obj = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        obj = context.Handler.CreateBlankNode();
                        TryParseCollection(context, obj);
                    }
                    break;

                case Token.LEFTSQBRACKET:
                    // Start of a Blank Node collection?
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        // An anonymous Blank Node
                        context.Tokens.Dequeue();
                        obj = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        // Start of a Blank Node Collection
                        obj = context.Handler.CreateBlankNode();
                        TryParsePredicateObjectList(context, obj, true);
                    }
                    break;

                case Token.LITERAL:
                case Token.LITERALWITHDT:
                case Token.LITERALWITHLANG:
                case Token.LONGLITERAL:
                case Token.PLAINLITERAL:
                    obj = TryParseLiteral(context, objToken);
                    break;

                case Token.RIGHTSQBRACKET:
                    if (bnodeList)
                    {
                        if (obj != null)
                        {
                            // Ok to return if we've seen a Triple
                            return;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Right Square Bracket encountered, expecting a valid object for the current Blank Node Predicate Object list", objToken);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Right Square Bracket encountered but not expecting the end of a Blank Node Predicate Object list", objToken);
                    }

                case Token.SEMICOLON:
                    if (obj != null)
                    {
                        // Ok to return if we've seen a Triple
                        return;
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Semicolon Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                    }

                case Token.QNAME:
                case Token.URI:
                    obj = ParserHelper.TryResolveUri(context, objToken, false, context.QNameUnescapeFunction);
                    break;

                case Token.EOF:
                    throw ParserHelper.Error("Unexpected end of file while trying to parse an Object list", objToken);

                default:
                    throw ParserHelper.Error("Unexpected Token '" + objToken.GetType().ToString() + "' encountered while trying to parse an Object list", objToken);
                }

                // Assert the Triple
                if (!context.Handler.HandleTriple(new Triple(subj, pred, obj)))
                {
                    ParserHelper.Stop();
                }

                // Expect a comma/semicolon/dot terminator if we are to continue
                next = context.Tokens.Peek();
                if (bnodeList)
                {
                    // If in a Blank Node list a dot is not permitted but a ] is
                    if (next.TokenType != Token.COMMA && next.TokenType != Token.SEMICOLON && next.TokenType != Token.RIGHTSQBRACKET)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Blank Node Object List, expected a comma, semicolon or ] to terminate the current Triple/list", next);
                    }
                }
                else if (next.TokenType != Token.COMMA && next.TokenType != Token.SEMICOLON && next.TokenType != Token.DOT)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse an Object list, expected a comma, semicolon or dot to terminate the current Triple", next);
                }
            } while (true);
        }
        /// <summary>
        /// Tries to parse Base/Prefix declarations.
        /// </summary>
        /// <param name="context">Parse Context.</param>
        /// <param name="turtleStyle">Whether declarations are Turtle style (if false SPARQL style is assumed).</param>
        private void TryParseDirective(TurtleParserContext context, bool turtleStyle)
        {
            if (context.TraceParsing)
            {
                Console.WriteLine("Attempting to parse a Base/Prefix Declaration");
            }

            if (!turtleStyle && context.Syntax == TurtleSyntax.Original)
            {
                throw ParserHelper.Error("SPARQL style BASE/PREFIX declarations are not permitted in this Turtle syntax", context.Tokens.Dequeue());
            }

            // If we've been called with turtleStyle set then an AT token has been encountered which we can discard
            if (turtleStyle)
            {
                context.Tokens.Dequeue();
            }

            // Then we expect either a Base Directive/Prefix Directive
            IToken directive = context.Tokens.Dequeue();

            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                // Then expect a Uri for the Base Uri
                IToken u = context.Tokens.Dequeue();
                if (u.TokenType == Token.URI)
                {
                    // Set the Base Uri resolving against the current Base if any
                    try
                    {
                        Uri baseUri = UriFactory.Create(Tools.ResolveUri(u.Value, context.BaseUri.ToSafeString()));
                        context.BaseUri = baseUri;
                        if (!context.Handler.HandleBaseUri(baseUri))
                        {
                            ParserHelper.Stop();
                        }
                    }
                    catch (RdfException rdfEx)
                    {
                        throw new RdfParseException("Unable to set the Base URI to '" + u.Value + "' due to the following error:\n" + rdfEx.Message, u, rdfEx);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + u.GetType().ToString() + "' encountered, expected a URI after a Base Directive", u);
                }
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                // Expect a Prefix then a Uri
                IToken pre = context.Tokens.Dequeue();
                if (pre.TokenType == Token.PREFIX)
                {
                    IToken ns = context.Tokens.Dequeue();
                    if (ns.TokenType == Token.URI)
                    {
                        // Register a Namespace resolving the Namespace Uri against the Base Uri
                        try
                        {
                            Uri    nsUri    = UriFactory.Create(Tools.ResolveUri(ns.Value, context.BaseUri.ToSafeString()));
                            String nsPrefix = (pre.Value.Length > 1) ? pre.Value.Substring(0, pre.Value.Length - 1) : String.Empty;
                            context.Namespaces.AddNamespace(nsPrefix, nsUri);
                            if (!context.Handler.HandleNamespace(nsPrefix, nsUri))
                            {
                                ParserHelper.Stop();
                            }
                        }
                        catch (RdfException rdfEx)
                        {
                            throw new RdfParseException("Unable to resolve the Namespace URI '" + ns.Value + "' due to the following error:\n" + rdfEx.Message, ns, rdfEx);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + ns.GetType().ToString() + "' encountered, expected a URI after a Prefix Directive", pre);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + pre.GetType().ToString() + "' encountered, expected a Prefix after a Prefix Directive", pre);
                }
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix Directive after an @ symbol", directive);
            }

            // Turtle sytle declarations are terminated with a Dot
            IToken terminator = context.Tokens.Peek();

            if (terminator.TokenType != Token.DOT)
            {
                // If Turtle style the terminating . is required
                if (turtleStyle)
                {
                    throw ParserHelper.Error("Unexpected Token '" + terminator.GetType().ToString() + "' encountered, expected a . to terminate a Base/Prefix Directive", terminator);
                }
            }
            else if (turtleStyle)
            {
                // Discard the . terminator for Turtle sytle declarations
                context.Tokens.Dequeue();
            }
            else
            {
                // For SPARQL style the . terminator is forbidden
                throw ParserHelper.Error("Unexpected Token '" + terminator.GetType().ToString() + "' encountered, a . is not permitted/required to terminate a SPARQL style Base/Prefix Directive", terminator);
            }
        }
        /// <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;
            }
        }
Exemple #23
0
        private void Parse(RdfACoreParserContext context)
        {
            try
            {
                context.Handler.StartRdf();

                //Initialise Term Mappings
                context.HostLanguage.InitTermMappings(context);

                IRdfAEvent current;
                bool       first   = true;
                int        nesting = 0;
                INode      rdfType = context.Handler.CreateUriNode(new Uri(RdfSpecsHelper.RdfType));
                List <IncompleteTriple> localIncompletes = new List <IncompleteTriple>();

                do
                {
                    localIncompletes.Clear();

                    //Dequeue the next event and increment/decrement nesting as appropriate
                    current = context.Events.Dequeue();
                    switch (current.EventType)
                    {
                    case Event.Element:
                        nesting++;
                        context.IncrementNesting();
                        break;

                    case Event.EndElement:
                        context.DecrementNesting();
                        nesting--;
                        continue;

                    default:
                        //Otherwise skip the event and continue
                        continue;
                        //throw new RdfParseException("Encountered an unexpected event of type '" + current.GetType().ToString() + "' when an Element/End Element event was expected", current.Position);
                    }
                    //Stop when nesting level returns to 0
                    if (nesting == 0)
                    {
                        break;
                    }

                    //Step 1 - Initialisation
                    bool  skip = false;
                    INode newSubj = null, currObjResource = null, currObjLiteral = null;

                    //Before carrying out further steps allow host specific special actions
                    context.HostLanguage.ParseExtensions(context, current);

                    //Step 2 - @profile parsing
                    if (current.HasAttribute("profile"))
                    {
                        if (!this.ParseProfileAttribute(context, current))
                        {
                            //If an @profile attribute fails to parse then must ignore the current subtree
                            int        i = 0;
                            IRdfAEvent next;
                            do
                            {
                                next = context.Events.Dequeue();
                                //Keep track of nesting in the subtree
                                if (next.EventType == Event.Element)
                                {
                                    i++;
                                }
                                if (next.EventType == Event.EndElement)
                                {
                                    i--;
                                }
                            } while (i > 0 && next.EventType != Event.EndElement && context.Events.Count > 0);

                            //If couldn't ignore a valid subtree then error
                            if (context.Events.Count == 0)
                            {
                                throw new RdfParseException("Encountered an @profile attribute which pointed to a malformed profile which meant the relevant subtree of the document should be ignored but the document does not contain a well formed subtree");
                            }

                            //If a bad @profile then continue after we've ignored the subtree
                            continue;
                        }
                    }

                    //Step 3 - @vocab parsing
                    if (current.HasAttribute("vocab"))
                    {
                        this.ParseVocabAttribute(context, current);
                    }

                    //Step 4 - @prefix parsing (plus any other mechanisms defined by the host language)
                    if (current.HasAttribute("prefix"))
                    {
                        this.ParsePrefixAttribute(context, current);
                    }
                    context.HostLanguage.ParsePrefixMappings(context, current);

                    //Step 5 - Language parsing
                    context.HostLanguage.ParseLiteralLanguage(context, current);

                    if (!current.HasAttribute("rel") && !current.HasAttribute("rev"))
                    {
                        //Step 6 - If no @rel or @rev establish a subject
                        newSubj = this.ParseSubject(context, current, nesting == 1, out skip);
                    }
                    else
                    {
                        //Step 7 - Use @rel or @rev to establish a subject and an object resource
                        newSubj         = this.ParseRelOrRevSubject(context, current, nesting == 1);
                        currObjResource = this.ParseObjectResource(context, current);
                    }

                    //Step 8 - If there is a non-null subject process @typeof
                    if (newSubj != null)
                    {
                        if (current.HasAttribute("typeof"))
                        {
                            foreach (INode n in this.ParseTypeofAttribute(context, current))
                            {
                                if (!context.Handler.HandleTriple(new Triple(newSubj, rdfType, n)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                        }
                    }

                    if (currObjResource != null)
                    {
                        //Step 9 - If there is a non-null object resource generate triples
                        if (current.HasAttribute("rel"))
                        {
                            foreach (INode n in this.ParseRelAttribute(context, current))
                            {
                                if (!context.Handler.HandleTriple(new Triple(newSubj, n, currObjResource)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                        }
                        if (current.HasAttribute("rev"))
                        {
                            foreach (INode n in this.ParseRevAttribute(context, current))
                            {
                                if (!context.Handler.HandleTriple(new Triple(currObjResource, n, newSubj)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                        }
                    }
                    else if (newSubj != null)
                    {
                        //Step 10 - If there is no object resource but there are predicates generate incomplete triples
                        currObjResource = context.Handler.CreateBlankNode();
                        if (current.HasAttribute("rel"))
                        {
                            foreach (INode n in this.ParseRelAttribute(context, current))
                            {
                                localIncompletes.Add(new IncompleteTriple(n, IncompleteTripleDirection.Forward));
                            }
                        }
                        if (current.HasAttribute("rev"))
                        {
                            foreach (INode n in this.ParseRevAttribute(context, current))
                            {
                                localIncompletes.Add(new IncompleteTriple(n, IncompleteTripleDirection.Reverse));
                            }
                        }
                    }

                    //Step 11 - Establish the current object literal
                    if (newSubj != null && current.HasAttribute("property"))
                    {
                        //Must be an @property attribute in order for any triples to be generated
                        List <INode> ps = this.ParsePropertyAttribute(context, current).ToList();

                        if (ps.Count > 0)
                        {
                            Uri dtUri;
                            if (current.HasAttribute("content"))
                            {
                                //If @content is present then either a plain/typed literal
                                if (current.HasAttribute("datatype"))
                                {
                                    //@datatype is present so typed literal
                                    dtUri          = this.ParseUri(context, current["datatype"], RdfACurieMode.TermOrCurieOrAbsUri);
                                    currObjLiteral = context.Handler.CreateLiteralNode(current["content"], dtUri);
                                }
                                else
                                {
                                    //Plain literal
                                    currObjLiteral = context.Handler.CreateLiteralNode(current["content"], context.Language);
                                }
                            }
                            else if (current.HasAttribute("datatype"))
                            {
                                //Typed literal
                                dtUri = this.ParseUri(context, current["datatype"], RdfACurieMode.TermOrCurieOrAbsUri);
                                if (dtUri != null)
                                {
                                    if (dtUri.ToString().Equals(RdfSpecsHelper.RdfXmlLiteral))
                                    {
                                        //XML Literal using element content
                                        currObjLiteral = context.Handler.CreateLiteralNode(this.ParseXmlContent(context), dtUri);
                                    }
                                    else
                                    {
                                        //Typed Literal using element content
                                        currObjLiteral = context.Handler.CreateLiteralNode(this.ParseTextContent(context), dtUri);
                                    }
                                }
                                else
                                {
                                    //If datatype does not resolve fall back to plain literal using element content
                                    currObjLiteral = context.Handler.CreateLiteralNode(this.ParseTextContent(context), context.Language);
                                }
                            }
                            else
                            {
                                //Plain Literal using element content
                                currObjLiteral = context.Handler.CreateLiteralNode(this.ParseTextContent(context), context.Language);
                            }

                            //Generate the relevant triples
                            foreach (INode p in ps)
                            {
                                if (!context.Handler.HandleTriple(new Triple(newSubj, p, currObjLiteral)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                        }
                    }

                    //Step 12 - Complete any existing incomplete triples
                    if (!skip && newSubj != null)
                    {
                        foreach (IncompleteTriple t in context.IncompleteTriples)
                        {
                            if (t.Direction == IncompleteTripleDirection.Forward)
                            {
                                if (!context.Handler.HandleTriple(new Triple(context.ParentSubject, t.Predicate, newSubj)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                            else
                            {
                                if (!context.Handler.HandleTriple(new Triple(newSubj, t.Predicate, context.ParentSubject)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                        }
                        context.IncompleteTriples.Clear();
                    }

                    //Step 13 - Set up for processing child elements if necessary
                    //Can skip this if the next event is an end element
                    if (context.Events.Peek().EventType != Event.EndElement)
                    {
                        context.ParentSubject = newSubj;
                        if (currObjResource != null)
                        {
                            context.ParentObject = currObjResource;
                        }
                        else if (newSubj != null)
                        {
                            context.ParentObject = newSubj;
                        }
                        else
                        {
                            context.ParentObject = context.ParentSubject;
                        }
                        context.IncompleteTriples.AddRange(localIncompletes);
                    }
                } while (context.Events.Count > 0);

                if (context.Events.Count > 0)
                {
                    throw new RdfParseException("Source document is malformed! Encountered an end element which closes the document element but there are still more elements to be parsed", current.Position);
                }

                context.Handler.EndRdf(true);
            }
            catch (RdfParsingTerminatedException)
            {
                context.Handler.EndRdf(true);
            }
            catch
            {
                context.Handler.EndRdf(false);
                throw;
            }
        }
Exemple #24
0
        private void Parse(TriGParserContext context)
        {
            try
            {
                context.Handler.StartRdf();

                //Expect a BOF Token
                IToken first = context.Tokens.Dequeue();
                if (first.TokenType != Token.BOF)
                {
                    throw ParserHelper.Error("Unexpected Token '" + first.GetType().ToString() + "' encountered, expected a BOF Token", first);
                }

                //Expect either a Directive or a Graph
                IToken next;
                do
                {
                    next = context.Tokens.Peek();
                    switch (next.TokenType)
                    {
                    case Token.COMMENT:
                        //Discard
                        context.Tokens.Dequeue();
                        break;

                    case Token.EOF:
                        //End of File
                        context.Tokens.Dequeue();
                        break;

                    case Token.BASEDIRECTIVE:
                    case Token.PREFIXDIRECTIVE:
                        //Parse a Directive
                        this.TryParseDirective(context);
                        break;

                    case Token.QNAME:
                    case Token.URI:
                    case Token.LEFTCURLYBRACKET:
                        //Parse a Graph

                        if (context.Syntax != TriGSyntax.Original)
                        {
                            //We must take care here because @prefix and @base directives may be Graph scoped so anything visible currently
                            //remains visible and must be restored afterwards but anything inside the Graph is not visible outside of it
                            Uri extBase            = context.BaseUri;
                            INamespaceMapper nsmap = new NamespaceMapper(context.Namespaces);

                            this.TryParseGraph(context);

                            //After we parse the Graph restore the state
                            if (!context.Handler.HandleBaseUri(extBase))
                            {
                                ParserHelper.Stop();
                            }
                            context.BaseUri = extBase;
                            context.Namespaces.Clear();
                            foreach (String prefix in nsmap.Prefixes)
                            {
                                if (!context.Handler.HandleNamespace(prefix, nsmap.GetNamespaceUri(prefix)))
                                {
                                    ParserHelper.Stop();
                                }
                            }
                            context.Namespaces.Import(nsmap);
                        }
                        else
                        {
                            //With the old syntax declarations are file scoped so no need to worry about graph scoping
                            this.TryParseGraph(context);
                        }
                        break;

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next);
                    }
                } while (next.TokenType != Token.EOF);

                context.Handler.EndRdf(true);
            }
            catch (RdfParsingTerminatedException)
            {
                context.Handler.EndRdf(true);
                //Discard this - it justs means the Handler told us to stop
            }
            catch
            {
                context.Handler.EndRdf(false);
                throw;
            }
        }
        /// <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;
            }
        }