Exemple #1
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'parseTypeCollectionPropertyElt'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="eventlist">Queue of Events that make up the Collection Parse Type Property Element and its Children</param>
        /// <param name="parent">Parent Event (ie. Node) of the Property Element</param>
        private void GrammarProductionParseTypeCollectionPropertyElement(RdfXmlParserContext context, IEventQueue<IRdfXmlEvent> eventlist, IRdfXmlEvent parent)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTracePartial("Parse Type Collection Property Element");
            }

            //Get the first Event, should be an ElementEvent
            //Type checking is done by the Parent Production
            IRdfXmlEvent first = eventlist.Dequeue();
            ElementEvent element = (ElementEvent)first;
            if (this._traceparsing) this.ProductionTracePartial(element);

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            //Validate Attributes
            String ID = String.Empty;
            if (element.Attributes.Count > 2)
            {
                //Can't be more than 2 Attributes, only allowed an optional rdf:ID and a required rdf:parseType
                throw ParserHelper.Error("An Property Element with Parse Type 'Collection' was encountered with too many Attributes.  Only rdf:ID and rdf:parseType are allowed on Property Elements with Parse Type 'Collection'", "Parse Type Collection Property Element", element);
            }
            else
            {
                //Check the attributes that do exist
                foreach (AttributeEvent a in element.Attributes)
                {
                    if (RdfXmlSpecsHelper.IsIDAttribute(a))
                    {
                        ID = "#" + a.Value;
                    }
                    else if (a.QName.Equals("rdf:parseType"))
                    {
                        //OK
                    }
                    else
                    {
                        //Invalid Attribute
                        throw ParserHelper.Error("Unexpected Attribute '" + a.QName + "' was encountered on a Property Element with Parse Type 'Collection'.  Only rdf:ID and rdf:parseType are allowed on Property Elements with Parse Type 'Collection'", "Parse Type Collection Property Element", element);
                    }
                }
            }

            //Build sequence of Blank Nodes
            IRdfXmlEvent next;
            IRdfXmlEvent nodeElement;

            Queue<ElementEvent> seqNodes = new Queue<ElementEvent>();
            while (eventlist.Count > 1)
            {
                #region Node Element Processing
                //Need to process the Node Element first

                //Create a new Sublist
                IEventQueue<IRdfXmlEvent> subevents = new EventQueue<IRdfXmlEvent>();
                int nesting = 0;
                nodeElement = eventlist.Peek();

                //Add Node Element to sequence
                seqNodes.Enqueue((ElementEvent)nodeElement);

                //Gather the Sublist taking account of nesting
                do
                {
                    next = eventlist.Dequeue();
                    subevents.Enqueue(next);

                    if (next is ElementEvent)
                    {
                        nesting++;
                    }
                    else if (next is EndElementEvent)
                    {
                        nesting--;
                    }
                } while (nesting > 0);

                //Call the next Grammar Production
                this.GrammarProductionNodeElement(context, subevents);

                #endregion
            }

            //Build a triple expressing the start of the list (which may be an empty list)
            INode subj, pred, obj;
            INode firstPred, restPred;
            INode b1, b2;

            //Subject comes from Parent
            ElementEvent parentElement = (ElementEvent)parent;
            subj = parentElement.SubjectNode;

            //Validate the ID (if any)
            if (!ID.Equals(String.Empty))
            {
                this.ValidateID(context, ID.Substring(1), subj);
            }

            //Predicate from the Element
            pred = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);

            if (seqNodes.Count > 0)
            {
                //Non-empty list
                ElementEvent node;

                //Get first Element from the Queue
                node = seqNodes.Dequeue();

                //Object is first thing in the Sequence which we create a Blank Node for
                b1 = context.Handler.CreateBlankNode();

                //Assert
                if (!context.Handler.HandleTriple(new Triple(subj, pred, b1))) ParserHelper.Stop();

                //Reify if applicable
                if (!ID.Equals(String.Empty))
                {
                    //Resolve the Uri
                    UriReferenceEvent uriref = new UriReferenceEvent(ID, String.Empty);
                    IUriNode uri = this.Resolve(context, uriref, element.BaseUri);

                    this.Reify(context, uri, subj, pred, b1);
                }

                //Set the first element in the list
                subj = b1;
                firstPred = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListFirst));
                if (!context.Handler.HandleTriple(new Triple(subj, firstPred, node.SubjectNode))) ParserHelper.Stop();

                //Middle elements of the list
                restPred = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListRest));
                while (seqNodes.Count >= 1)
                {
                    node = seqNodes.Dequeue();

                    //Set Node 2 to be the rest of the previous items list
                    b2 = context.Handler.CreateBlankNode();
                    if (!context.Handler.HandleTriple(new Triple(b1, restPred, b2))) ParserHelper.Stop();

                    //Set Node 2 to be the start of it's own list
                    if (!context.Handler.HandleTriple(new Triple(b2, firstPred, node.SubjectNode))) ParserHelper.Stop();

                    b1 = b2;
                }

                //Set last element of the list to have its rest as nil
                if (!context.Handler.HandleTriple(new Triple(b1, restPred, context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil))))) ParserHelper.Stop();
            }
            else
            {
                //Empty list

                //Object is therefore rdf:nil
                obj = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));

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

                //Reify if applicable
                if (!ID.Equals(String.Empty))
                {
                    //Resolve the Uri
                    UriReferenceEvent uriref = new UriReferenceEvent(ID, String.Empty);
                    IUriNode uri = this.Resolve(context, uriref, element.BaseUri);

                    this.Reify(context, uri, subj, pred, obj);
                }
            }

            //Check last event is an EndElementEvent
            next = eventlist.Dequeue();
            if (!(next is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', expected an EndElementEvent to terminate a Parse Type Collection Property Element!", "Parse Type Collection Property Element", next);
            }
        }
Exemple #2
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'nodeElement'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="eventlist">Queue of Events that make up the Node Element and its Children to apply the Production to</param>
        private void GrammarProductionNodeElement(RdfXmlParserContext context, IEventQueue<IRdfXmlEvent> eventlist)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTracePartial("Node Element");
            }

            //Get First Event in the Queue
            IRdfXmlEvent first = eventlist.Dequeue();

            //Check it's an ElementEvent
            if (!(first is ElementEvent))
            {
                //Unexpected Event
                throw ParserHelper.Error("Expected an ElementEvent but encountered a '" + first.GetType().ToString() + "'", "Node Element", first);
            }

            //Check it has a valid Uri
            ElementEvent element = (ElementEvent)first;
            if (this._traceparsing) this.ProductionTracePartial(element);
            this.ApplyNamespaces(context, element);
            if (!RdfXmlSpecsHelper.IsNodeElementUri(element.QName))
            {
                throw ParserHelper.Error("A Node Element was encountered with an invalid URI '" + element.QName + "' \nCore Syntax Terms, Old Syntax Terms and rdf:li cannot be used as Node Element URIs", "Node Element", element);
            }

            //Check the set of Attributes is Valid
            int limitedAttributesFound = 0;
            String ID = String.Empty;
            foreach (AttributeEvent attr in element.Attributes)
            {
                if (RdfXmlSpecsHelper.IsIDAttribute(attr))
                {
                    ID = attr.Value;
                    limitedAttributesFound++;

                    //Set the Subject
                    element.Subject = new UriReferenceEvent("#" + attr.Value, attr.SourceXml);
                }
                else if (RdfXmlSpecsHelper.IsNodeIDAttribute(attr))
                {
                    limitedAttributesFound++;

                    //Validate the Node ID
                    if (!XmlSpecsHelper.IsName(attr.Value))
                    {
                        throw ParserHelper.Error("The value '" + attr.Value + "' for rdf:nodeID is not valid, RDF Node IDs can only be valid Names as defined by the W3C XML Specification", "Node Element", attr);
                    }

                    //Set the Subject
                    element.Subject = new BlankNodeIDEvent(attr.Value, attr.SourceXml);
                }
                else if (RdfXmlSpecsHelper.IsAboutAttribute(attr))
                {
                    limitedAttributesFound++;

                    //Set the Subject
                    element.Subject = new UriReferenceEvent(attr.Value, attr.SourceXml);
                }
                else if (RdfXmlSpecsHelper.IsPropertyAttribute(attr))
                {
                    //Don't need to do anything here yet
                }
                else
                {
                    //Unknown and Unexpected Attribute Type
                    throw ParserHelper.Error("Unexpected Attribute '" + attr.QName + "' was encountered!", "Node Element", element);
                }

                //Can't have more than 1 of ID, Node ID or About Attributes
                if (limitedAttributesFound > 1)
                {
                    throw ParserHelper.Error("A Node Element can only have 1 of the following attributes: rdf:id, rdf:nodeID, rdf:about", "Node Element", element);
                }
            }

            //Generate a Blank Node ID if our Subject is empty
            if (element.Subject == null)
            {
                element.Subject = new BlankNodeIDEvent(element.SourceXml);
            }

            //Add statements as necessary
            INode subj, pred, obj;
            if (element.SubjectNode == null)
            {
                //Don't always want to drop in here since the SubjectNode may already be set elsewhere
                if (element.Subject is UriReferenceEvent)
                {
                    UriReferenceEvent uri = (UriReferenceEvent)element.Subject;
                    subj = this.Resolve(context, uri, element.BaseUri);
                }
                else if (element.Subject is BlankNodeIDEvent)
                {
                    BlankNodeIDEvent blank = (BlankNodeIDEvent)element.Subject;

                    //Select whether we need to generate an ID or if there's one given for the Blank Node
                    //Note that we let the Graph class handle generation of IDs
                    if (blank.Identifier.Equals(String.Empty))
                    {
                        subj = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        subj = context.Handler.CreateBlankNode(blank.Identifier);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Subject generated for a Triple", "Node Element", element.Subject);
                }
            } else {
                subj = element.SubjectNode;
            }

            //Set the Subject Node property of the Event for later reuse
            element.SubjectNode = subj;

            //Validate the ID (if any)
            if (!ID.Equals(String.Empty))
            {
                this.ValidateID(context, ID, subj);
            }

            if (!element.QName.Equals("rdf:Description") && !element.QName.Equals(":Description"))
            {
                //Assert a Triple regarding Type
                pred = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType));
                obj = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);
                if (!context.Handler.HandleTriple(new Triple(subj, pred, obj))) ParserHelper.Stop();
            }

            //Go back over Attributes looking for property attributes
            foreach (AttributeEvent attr in element.Attributes)
            {
                if (RdfXmlSpecsHelper.IsPropertyAttribute(attr))
                {
                    if (attr.QName.Equals("rdf:type"))
                    {
                        //Generate a Type Triple
                        pred = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType));

                        //Resolve URIRef into a Uri Node
                        UriReferenceEvent uriref = new UriReferenceEvent(attr.Value, attr.SourceXml);
                        obj = this.Resolve(context, uriref, element.BaseUri);

                        if (!context.Handler.HandleTriple(new Triple(subj, pred, obj))) ParserHelper.Stop();
                    }
                    else
                    {
                        //Generate a Property Triple
                        pred = context.Handler.CreateUriNode(UriFactory.Create(Tools.ResolveQName(attr.QName, context.Namespaces, context.BaseUri)));

                        //Add Language to Literal if necessary
                        if (element.Language.Equals(String.Empty))
                        {
                            obj = context.Handler.CreateLiteralNode(attr.Value);
                        }
                        else
                        {
                            obj = context.Handler.CreateLiteralNode(attr.Value, element.Language);
                        }

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

            //Handle Child Elements
            IEventQueue<IRdfXmlEvent> children = new EventQueue<IRdfXmlEvent>();
            while (eventlist.Count > 1)
            {
                children.Enqueue(eventlist.Dequeue());
            }
            if (children.Count > 0) this.GrammarProductionPropertyElementList(context, children, element);

            //Check Last Event in queue is an EndElement event
            IRdfXmlEvent last = eventlist.Dequeue();
            if (!(last is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + last.GetType().ToString() + "', expected an EndElement Event", "NodeElement", last);
            }
        }
Exemple #3
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'nodeElementList'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="eventlist">Queue of Events to apply the Production to</param>
        private void GrammarProductionNodeElementList(RdfXmlParserContext context, IEventQueue<IRdfXmlEvent> eventlist)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTrace("Node Element List");
            }

            IRdfXmlEvent next;

            //Want to break up into a number of sublists
            while (eventlist.Count > 0)
            {
                //Create a new Sublist
                IEventQueue<IRdfXmlEvent> subevents = new EventQueue<IRdfXmlEvent>();
                int nesting = 0;

                //Gather the Sublist taking account of nesting
                do
                {
                    next = eventlist.Dequeue();
                    subevents.Enqueue(next);

                    if (next is ElementEvent)
                    {
                        nesting++;
                    }
                    else if (next is EndElementEvent)
                    {
                        nesting--;
                    }
                } while (nesting > 0);

                //Call the next Grammar Production
                this.GrammarProductionNodeElement(context, subevents);
            }
        }
Exemple #4
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'emptyPropertyElt'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="element">Element Event for the Empty Property Element</param>
        /// <param name="parent">Parent Event (ie. Node) of the Property Element</param>
        private void GrammarProductionEmptyPropertyElement(RdfXmlParserContext context, ElementEvent element, IRdfXmlEvent parent)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTrace("Empty Property Element");
            }

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            INode subj, pred, obj;
            ElementEvent parentEl;

            //Are there any attributes OR Only a rdf:ID attribute?
            if (element.Attributes.Count == 0 || (element.Attributes.Count == 1 && RdfXmlSpecsHelper.IsIDAttribute(element.Attributes[0])))
            {
                //No Attributes/Only rdf:ID

                //Get the Subject Node from the Parent
                parentEl = (ElementEvent)parent;
                subj = parentEl.SubjectNode;

                //Create the Predicate from the Element
                pred = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);

                //Create the Object
                if (!element.Language.Equals(String.Empty))
                {
                    obj = context.Handler.CreateLiteralNode(String.Empty, element.Language);
                }
                else
                {
                    obj = context.Handler.CreateLiteralNode(String.Empty);
                }

                //Make the Assertion
                if (!context.Handler.HandleTriple(new Triple(subj, pred, obj))) ParserHelper.Stop();

                //Reifiy if applicable
                if (element.Attributes.Count == 1)
                {
                    //Validate the ID
                    this.ValidateID(context, element.Attributes[0].Value, subj);

                    //Resolve the Uri
                    UriReferenceEvent uriref = new UriReferenceEvent("#" + element.Attributes[0].Value, String.Empty);
                    IUriNode uri = this.Resolve(context, uriref, element.BaseUri);

                    this.Reify(context, uri, subj, pred, obj);
                }

            }
            else if (element.Attributes.Count > 0 && element.Attributes.Where(a => RdfXmlSpecsHelper.IsDataTypeAttribute(a)).Count() == 1)
            {
                //Should be processed as a Typed Literal Event instead
                EventQueue<IRdfXmlEvent> temp = new EventQueue<IRdfXmlEvent>();
                temp.Enqueue(element);
                temp.Enqueue(new TextEvent(String.Empty, String.Empty));
                temp.Enqueue(new EndElementEvent());
                this.GrammarProductionLiteralPropertyElement(context, temp, parent);
                return;
            }
            else
            {

                //Check through attributes
                IRdfXmlEvent res = null;

                //Check through attributes to decide the Subject of the Triple(s)
                String ID = String.Empty;
                int limitedAttributes = 0;
                foreach (AttributeEvent a in element.Attributes)
                {
                    if (RdfXmlSpecsHelper.IsResourceAttribute(a))
                    {
                        //An rdf:resource attribute so a Uri Reference
                        res = new UriReferenceEvent(a.Value, a.SourceXml);
                        limitedAttributes++;
                    }
                    else if (RdfXmlSpecsHelper.IsNodeIDAttribute(a))
                    {
                        //An rdf:nodeID attribute so a Blank Node

                        //Validate the Node ID
                        if (!XmlSpecsHelper.IsName(a.Value))
                        {
                            //Invalid nodeID
                            throw ParserHelper.Error("The value '" + a.Value + "' for rdf:nodeID is not valid, RDF Node IDs can only be valid Names as defined by the W3C XML Specification", "Empty Property Element", a);
                        }
                        res = new BlankNodeIDEvent(a.Value, a.SourceXml);
                        limitedAttributes++;
                    }
                    else if (RdfXmlSpecsHelper.IsIDAttribute(a))
                    {
                        //Set the ID for later use in reification
                        ID = "#" + a.Value;
                    }

                    //Check we haven't got more than 1 of the Limited Attributes
                    if (limitedAttributes > 1)
                    {
                        throw ParserHelper.Error("A Property Element can only have 1 of the following attributes: rdf:nodeID or rdf:resource", "Empty Property Element", element);
                    }
                }
                if (res == null)
                {
                    //No relevant attributes so an anonymous Blank Node
                    res = new BlankNodeIDEvent(String.Empty);
                }

                //Now create the actual Subject Node
                if (res is UriReferenceEvent)
                {
                    //Resolve the Uri Reference
                    UriReferenceEvent uriref = (UriReferenceEvent)res;
                    subj = this.Resolve(context, uriref, element.BaseUri);
                }
                else if (res is BlankNodeIDEvent)
                {
                    BlankNodeIDEvent blank = (BlankNodeIDEvent)res;
                    if (blank.Identifier.Equals(String.Empty))
                    {
                        //Have the Graph generate a Blank Node ID
                        subj = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        //Use the supplied Blank Node ID
                        subj = context.Handler.CreateBlankNode(blank.Identifier);
                    }
                }
                else
                {
                    //Should never hit this case but required to get the Code to Compile
                    //Have the Graph generate a Blank Node ID
                    subj = context.Handler.CreateBlankNode();
                }

                //Validate the ID (if any)
                if (!ID.Equals(String.Empty))
                {
                    this.ValidateID(context, ID.Substring(1), subj);
                }

                //Relate the Property element to its parent
                parentEl = (ElementEvent)parent;
                pred = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);
                if (!context.Handler.HandleTriple(new Triple(parentEl.SubjectNode, pred, subj))) ParserHelper.Stop();

                //Reify if applicable
                if (!ID.Equals(String.Empty))
                {
                    //Resolve the Uri
                    UriReferenceEvent uriref = new UriReferenceEvent(ID, String.Empty);
                    IUriNode uri = this.Resolve(context, uriref, element.BaseUri);

                    this.Reify(context, uri, parentEl.SubjectNode, pred, subj);
                }

                //Process the rest of the Attributes
                foreach (AttributeEvent a in element.Attributes)
                {
                    if (a.QName.Equals("rdf:type"))
                    {
                        //A Property Attribute giving a Type

                        //Assert a Type Triple
                        UriReferenceEvent type = new UriReferenceEvent(a.Value, a.SourceXml);
                        pred = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType));
                        obj = this.Resolve(context, type, element.BaseUri);

                        if (!context.Handler.HandleTriple(new Triple(parentEl.SubjectNode, pred, obj))) ParserHelper.Stop();
                    }
                    else if (RdfXmlSpecsHelper.IsPropertyAttribute(a))
                    {
                        //A Property Attribute

                        //Validate the Normalization of the Attribute Value
            #if !NO_NORM
                        if (!a.Value.IsNormalized())
                        {
                            throw ParserHelper.Error("Encountered a Property Attribute '" + a.QName + "' whose value was not correctly normalized in Unicode Normal Form C", "Empty Property Element", a);
                        }
                        else
                        {
            #endif
                            //Create the Predicate from the Attribute QName
                            pred = context.Handler.CreateUriNode(UriFactory.Create(Tools.ResolveQName(a.QName, context.Namespaces, context.BaseUri)));

                            //Create the Object from the Attribute Value
                            if (element.Language.Equals(String.Empty))
                            {
                                obj = context.Handler.CreateLiteralNode(a.Value);
                            }
                            else
                            {
                                obj = context.Handler.CreateLiteralNode(a.Value, element.Language);
                            }

                            //Assert the Property Triple
                            if (!context.Handler.HandleTriple(new Triple(subj, pred, obj))) ParserHelper.Stop();
            #if !NO_NORM
                        }
            #endif
                    }
                    else if (RdfXmlSpecsHelper.IsIDAttribute(a) || RdfXmlSpecsHelper.IsNodeIDAttribute(a) || RdfXmlSpecsHelper.IsResourceAttribute(a))
                    {
                        //These have already been processed
                        //We test for them so that we can then throw ParserHelper.Errors in the final case for unexpected attributes
                    }
                    else
                    {
                        //Unexpected Attribute
                        throw ParserHelper.Error("Unexpected Attribute '" + a.QName + "' encountered on a Property Element!  Only rdf:ID, rdf:resource, rdf:nodeID and Property Attributes are permitted on Property Elements", "Empty Property Element", element);
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'resourcePropertyElt'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="eventlist">Queue of Events that make up the Resource Property Element and its Children</param>
        /// <param name="parent">Parent Event (ie. Node) of the Property Element</param>
        private void GrammarProductionResourcePropertyElement(RdfXmlParserContext context, IEventQueue<IRdfXmlEvent> eventlist, IRdfXmlEvent parent)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTracePartial("Resource Property Element");
            }

            //Cast to an ElementEvent
            //We don't validate type here since we know this will be an ElementEvent because the calling function
            //will have done this validation previously
            IRdfXmlEvent first = eventlist.Dequeue();
            IRdfXmlEvent next = eventlist.Peek();
            ElementEvent element = (ElementEvent)first;
            if (this._traceparsing) this.ProductionTracePartial(element);

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            //Only allowed one attribute max which must be an ID attribute
            String ID = String.Empty;
            if (element.Attributes.Count > 1)
            {
                throw ParserHelper.Error("A Resource Property Element contains too many Attributes, only rdf:ID is permitted", element);
            }
            else if (element.Attributes.Count == 1)
            {
                if (!RdfXmlSpecsHelper.IsIDAttribute(element.Attributes.First()))
                {
                    throw ParserHelper.Error("A Resource Property Element was encountered with a single attribute which was not rdf:ID, only rdf:ID is permitted", element);
                }
                else
                {
                    ID = element.Attributes.First().Value;
                }
            }

            //Next must be an ElementEvent
            if (!(next is ElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', expected an ElementEvent as the first Event in a Resource Property Elements Event list", next);
            }

            //Get list of Sub Events
            IEventQueue<IRdfXmlEvent> subevents = new EventQueue<IRdfXmlEvent>();
            while (eventlist.Count > 1)
            {
                subevents.Enqueue(eventlist.Dequeue());
            }
            this.GrammarProductionNodeElement(context, subevents);

            //Check Last is an EndElementEvent
            IRdfXmlEvent last = eventlist.Dequeue();
            if (!(last is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + last.GetType().ToString() + "', expected an EndElement Event", last);
            }

            //Now we can generate the relevant RDF
            INode subj, pred, obj;

            //Validate the Type of the Parent
            if (!(parent is ElementEvent))
            {
                throw ParserHelper.Error("Unexpected Parent Event '" + parent.GetType().ToString() + "', expected an ElementEvent", parent);
            }
            ElementEvent parentEl = (ElementEvent)parent;

            //Get the Subject Node from the Parent
            subj = parentEl.SubjectNode;

            //Validate the ID (if any)
            if (!ID.Equals(String.Empty))
            {
                this.ValidateID(context, ID, subj);
            }

            //Create a Predicate from this Element
            pred = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);

            //Get the Object Node from the Child Node
            ElementEvent child = (ElementEvent)next;
            obj = child.SubjectNode;

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

            //Add Reification where appropriate
            if (element.Attributes.Count == 1)
            {
                //Must be an rdf:ID attribute as we've validated this earlier

                //Get the Attribute Event and generate a Uri from it
                AttributeEvent attr = element.Attributes.First();
                UriReferenceEvent uriref = new UriReferenceEvent("#" + attr.Value, attr.SourceXml);
                IUriNode uri = this.Resolve(context, uriref, element.BaseUri);

                this.Reify(context, uri, subj, pred, obj);
            }
        }
Exemple #6
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'RDF'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="element">RDF Element to apply Production to</param>
        private void GrammarProductionRDF(RdfXmlParserContext context, ElementEvent element)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTrace("RDF", element);
            }

            //Check Uri is correct
            String localName = element.LocalName;
            String prefix = element.Namespace;
            if (localName.Equals("RDF") ||
                ((context.Namespaces.HasNamespace(prefix) && context.Namespaces.GetNamespaceUri(prefix).ToString().Equals(NamespaceMapper.RDF))
                 || element.NamespaceAttributes.Any(ns => ns.Prefix.Equals(prefix) && ns.Uri.Equals(NamespaceMapper.RDF))))
            {
                //This is OK
            }
            else
            {
                throw ParserHelper.Error("Unexpected Node '" + element.QName + "', an 'rdf:RDF' node was expected", "RDF", element);
            }
            //Check has no Attributes
            if (element.Attributes.Count > 0)
            {
                throw ParserHelper.Error("Root Node should not contain any attributes other than XML Namespace Declarations", "RDF", element);
            }

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            //Build a Sublist of all Nodes up to the matching EndElement
            IEventQueue<IRdfXmlEvent> subevents = new EventQueue<IRdfXmlEvent>();
            IRdfXmlEvent next;

            //Make sure we discard the current ElementEvent which will be at the front of the queue
            context.Events.Dequeue();

            //Gather the Sublist
            while (context.Events.Count > 1)
            {
                subevents.Enqueue(context.Events.Dequeue());
            }

            //Call the NodeElementList Grammer Production
            this.GrammarProductionNodeElementList(context, subevents);

            //Next Event in queue should be an EndElementEvent or we Error
            next = context.Events.Dequeue();
            if (!(next is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', an EndElementEvent was expected", "RDF", element);
            }
        }
Exemple #7
0
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'parseTypeResourcePropertyElt'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="eventlist">Queue of Events that make up the Resource Parse Type Property Element and its Children</param>
        /// <param name="parent">Parent Event (ie. Node) of the Property Element</param>
        private void GrammarProductionParseTypeResourcePropertyElement(RdfXmlParserContext context, IEventQueue<IRdfXmlEvent> eventlist, IRdfXmlEvent parent)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTracePartial("Parse Type Resource Property Element");
            }

            //Get the first Event, should be an ElementEvent
            //Type checking is done by the Parent Production
            IRdfXmlEvent first = eventlist.Dequeue();
            ElementEvent element = (ElementEvent)first;
            if (this._traceparsing) this.ProductionTracePartial(element);

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            //Validate Attributes
            String ID = String.Empty;
            if (element.Attributes.Count > 2)
            {
                //Can't be more than 2 Attributes, only allowed an optional rdf:ID and a required rdf:parseType
                throw ParserHelper.Error("An Property Element with Parse Type 'Resource' was encountered with too many Attributes.  Only rdf:ID and rdf:parseType are allowed on Property Elements with Parse Type 'Resource'", "Parse Type Resource Property Element", element);
            }
            else
            {
                //Check the attributes that do exist
                foreach (AttributeEvent a in element.Attributes)
                {
                    if (RdfXmlSpecsHelper.IsIDAttribute(a))
                    {
                        ID = "#" + a.Value;
                    }
                    else if (a.QName.Equals("rdf:parseType"))
                    {
                        //OK
                    }
                    else
                    {
                        //Invalid Attribute
                        throw ParserHelper.Error("Unexpected Attribute '" + a.QName + "' was encountered on a Property Element with Parse Type 'Resource'.  Only rdf:ID and rdf:parseType are allowed on Property Elements with Parse Type 'Resource'", "Parse Type Resource Property Element", element);
                    }
                }
            }

            //Add a Triple about this
            INode subj, pred, obj;

            //Get the Subject from the Parent
            ElementEvent parentEvent = (ElementEvent)parent;
            subj = parentEvent.SubjectNode;

            //Validate the ID (if any)
            if (!ID.Equals(String.Empty))
            {
                this.ValidateID(context, ID.Substring(1), subj);
            }

            //Create the Predicate from the Element
            pred = this.Resolve(context, element);//context.Handler.CreateUriNode(element.QName);

            //Generate a Blank Node ID for the Object
            obj = context.Handler.CreateBlankNode();

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

            //Reify if applicable
            if (!ID.Equals(String.Empty))
            {
                //Resolve the Uri
                UriReferenceEvent uriref = new UriReferenceEvent(ID, String.Empty);
                IUriNode uri = this.Resolve(context, uriref,element.BaseUri);

                this.Reify(context, uri, subj, pred, obj);
            }

            //Get the next event in the Queue which should be either an Element Event or a End Element Event
            //Validate this
            IRdfXmlEvent next = eventlist.Dequeue();
            if (next is EndElementEvent)
            {
                //Content is Empty so nothing else to do
            }
            else if (next is ElementEvent)
            {
                //Non-Empty Content so need to build a sequence of new events
                IEventQueue<IRdfXmlEvent> subEvents = new EventQueue<IRdfXmlEvent>();

                //Create an rdf:Description event as the container
                ElementEvent descrip = new ElementEvent("rdf:Description", element.BaseUri, String.Empty);
                descrip.Subject = new BlankNodeIDEvent(String.Empty);
                descrip.SubjectNode = obj;
                subEvents.Enqueue(descrip);

                //Add the current element we were looking at
                subEvents.Enqueue(next);

                //Add rest of events in list (exceot the last)
                while (eventlist.Count > 1)
                {
                    subEvents.Enqueue(eventlist.Dequeue());
                }

                //Terminate with an EndElement Event
                subEvents.Enqueue(new EndElementEvent());

                //Process with Node Element Production
                this.GrammarProductionNodeElement(context, subEvents);

                //Get the last thing in the List
                next = eventlist.Dequeue();
            }
            else
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', expected an ElementEvent or EndElementEvent after a Parse Type Resource Property Element!", "Parse Type Resource Property Element", next);
            }

            //Check for the last thing being an EndElement Event
            if (!(next is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', expected an EndElementEvent to terminate a Parse Type Resource Property Element!", "Parse Type Resource Property Element", next);
            }
        }
        /// <summary>
        /// Implementation of the RDF/XML Grammar Production 'RDF'
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="element">RDF Element to apply Production to</param>
        private void GrammarProductionRDF(RdfXmlParserContext context, ElementEvent element)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTrace("RDF");
            }

            //Check Uri is correct (using the QName for simplicity)
            if (!element.QName.Equals("rdf:RDF") && !element.QName.Equals(":RDF"))
            {
                throw ParserHelper.Error("Unexpected Node '" + element.QName + "', an 'rdf:RDF' node was expected", "RDF", element);
            }
            //Check has no Attributes
            if (element.Attributes.Count > 0)
            {
                throw ParserHelper.Error("Root Node should not contain any attributes other than XML Namespace Declarations", "RDF", element);
            }

            //Apply Namespaces
            this.ApplyNamespaces(context, element);

            //Build a Sublist of all Nodes up to the matching EndElement
            IEventQueue subevents = new EventQueue();
            IRdfXmlEvent next;

            //Make sure we discard the current ElementEvent which will be at the front of the queue
            context.Events.Dequeue();

            //Gather the Sublist
            while (context.Events.Count > 1)
            {
                subevents.Enqueue(context.Events.Dequeue());
            }

            //Call the NodeElementList Grammer Production
            this.GrammarProductionNodeElementList(context, subevents);

            //Next Event in queue should be an EndElementEvent or we Error
            next = context.Events.Dequeue();
            if (!(next is EndElementEvent))
            {
                throw ParserHelper.Error("Unexpected Event '" + next.GetType().ToString() + "', an EndElementEvent was expected", "RDF", element);
            }
        }