/// <summary>
        /// Given an XML Node creates the relevant RDF/XML Events for it and recurses as necessary
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="node">The Node to create Event(s) from</param>
        /// <param name="parent">The Parent Node of the given Node</param>
        /// <returns></returns>
        private ElementEvent GenerateEvents(RdfXmlParserContext context, XmlNode node, IRdfXmlEvent parent)
        {
            //Get the Base Uri
            String baseUri = String.Empty;
            if (parent is ElementEvent)
            {
                baseUri = ((ElementEvent)parent).BaseUri;
            }
            //Create an ElementEvent for the Node
            ElementEvent element = new ElementEvent(node.LocalName, node.Prefix, baseUri, node.OuterXml);

            //Set the initial Language from the Parent
            ElementEvent parentEl = (ElementEvent)parent;
            element.Language = parentEl.Language;

            #region Attribute Processing

            //Iterate over Attributes
            bool parseTypeLiteral = false;
            foreach (XmlAttribute attr in node.Attributes)
            {
                //Watch out for special attributes
                if (attr.Name == "xml:lang")
                {
                    //Set Language
                    element.Language = attr.Value;
                }
                else if (attr.Name == "xml:base")
                {
                    //Set Base Uri

                    if (RdfXmlSpecsHelper.IsAbsoluteURI(attr.Value))
                    {
                        //Absolute Uri
                        element.BaseUri = attr.Value;
                    }
                    else if (!element.BaseUri.Equals(String.Empty))
                    {
                        //Relative Uri with a Base Uri to resolve against
                        //element.BaseUri += attr.Value;
                        element.BaseUri = Tools.ResolveUri(attr.Value, element.BaseUri);
                    }
                    else
                    {
                        //Relative Uri with no Base Uri
                        throw new RdfParseException("Cannot resolve a Relative Base URI since there is no in-scope Base URI");
                    }
                }
                else if (attr.Prefix == "xmlns")
                {
                    //Register a Namespace
                    String uri;
                    if (attr.Value.StartsWith("http://"))
                    {
                        //Absolute Uri
                        uri = attr.Value;
                    }
                    else if (!element.BaseUri.Equals(String.Empty))
                    {
                        //Relative Uri with a Base Uri to resolve against
                        //uri = element.BaseUri + attr.Value;
                        uri = Tools.ResolveUri(attr.Value, element.BaseUri);
                    }
                    else
                    {
                        //Relative Uri with no Base Uri
                        throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI");
                    }
                    NamespaceAttributeEvent ns = new NamespaceAttributeEvent(attr.LocalName, uri, attr.OuterXml);
                    element.NamespaceAttributes.Add(ns);
                }
                else if (attr.Prefix == String.Empty && attr.Name == "xmlns")
                {
                    //Register a Default Namespace (Empty Prefix)
                    String uri;

                    if (attr.Value.StartsWith("http://"))
                    {
                        //Absolute Uri
                        uri = attr.Value;
                    }
                    else if (!element.BaseUri.Equals(String.Empty))
                    {
                        //Relative Uri with a Base Uri to resolve against
                        //uri = element.BaseUri + attr.Value;
                        uri = Tools.ResolveUri(attr.Value, element.BaseUri);
                    }
                    else
                    {
                        //Relative Uri with no Base Uri
                        throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI");
                    }
                    NamespaceAttributeEvent ns = new NamespaceAttributeEvent(String.Empty, uri, attr.OuterXml);
                    element.NamespaceAttributes.Add(ns);
                }
                else if (attr.Prefix == "xml" || (attr.Prefix == String.Empty && attr.LocalName.StartsWith("xml")))
                {
                    //Ignore other Reserved XML Names
                }
                else if (attr.Name == "rdf:parseType" && attr.Value == "Literal")
                {
                    //Literal Parse Type
                    parseTypeLiteral = true;

                    //Create the Attribute
                    AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml);
                    element.Attributes.Add(attrEvent);

                    //Set ParseType property correctly
                    element.ParseType = RdfXmlParseType.Literal;
                }
                else if (attr.Name == "rdf:parseType")
                {
                    //Some other Parse Type

                    //Create the Attribute
                    AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml);
                    element.Attributes.Add(attrEvent);

                    //Set the ParseType property correctly
                    if (attr.Value == "Resource")
                    {
                        element.ParseType = RdfXmlParseType.Resource;
                    }
                    else if (attr.Value == "Collection")
                    {
                        element.ParseType = RdfXmlParseType.Collection;
                    }
                    else
                    {
                        //Have to assume Literal
                        element.ParseType = RdfXmlParseType.Literal;
                        parseTypeLiteral = true;

                        //Replace the Parse Type attribute with one saying it is Literal
                        element.Attributes.Remove(attrEvent);
                        attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, "Literal", attr.OuterXml);
                    }
                }
                else
                {
                    //Normal Attribute which we generate an Event from
                    AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml);
                    element.Attributes.Add(attrEvent);
                }
            }

            //Validate generated Attributes for Namespace Confusion and URIRef encoding
            foreach (AttributeEvent a in element.Attributes)
            {
                //Namespace Confusion should only apply to Attributes without a Namespace specified
                if (a.Namespace.Equals(String.Empty))
                {
                    if (RdfXmlSpecsHelper.IsAmbigiousAttributeName(a.LocalName))
                    {
                        //Can't use any of the RDF terms that mandate the rdf: prefix without it
                        throw ParserHelper.Error("An Attribute with an ambigious name '" + a.LocalName + "' was encountered.  The following attribute names MUST have the rdf: prefix - about, aboutEach, ID, bagID, type, resource, parseType", element);
                    }
                }

                //URIRef encoding check
                if (!RdfXmlSpecsHelper.IsValidUriRefEncoding(a.Value))
                {
                    throw ParserHelper.Error("An Attribute with an incorrectly encoded URIRef was encountered, URIRef's must be encoded in Unicode Normal Form C", a);
                }
            }

            #endregion

            //Don't proceed if Literal Parse Type is on
            if (parseTypeLiteral)
            {
                //Generate an XMLLiteral from its Inner Xml (if any)
                TypedLiteralEvent lit = new TypedLiteralEvent(node.InnerXml.Normalize(), RdfSpecsHelper.RdfXmlLiteral, node.InnerXml);
                element.Children.Add(lit);
                return element;
            }

            //Are there Child Nodes?
            if (node.HasChildNodes)
            {
                //Take different actions depending on the Number and Type of Child Nodes
                if (node.ChildNodes.Count > 1)
                {
                    //Multiple Child Nodes

                    //Iterate over Child Nodes
                    foreach (XmlNode child in node.ChildNodes)
                    {
                        //Ignore Irrelevant Node Types
                        if (this.IsIgnorableNode(child))
                        {
                            continue;
                        }

                        //Generate an Event for the Child Node
                        ElementEvent childEvent = this.GenerateEvents(context, child, element);
                        element.Children.Add(childEvent);
                    }
                }
                else if (node.ChildNodes[0].NodeType == XmlNodeType.Text)
                {
                    //Single Child which is a Text Node

                    //Generate a Text Event
                    TextEvent text = new TextEvent(node.InnerText.Normalize(), node.OuterXml);
                    element.Children.Add(text);
                }
                else if (node.ChildNodes[0].NodeType == XmlNodeType.CDATA)
                {
                    //Single Child which is a CData Node

                    TextEvent text = new TextEvent(node.InnerXml.Normalize(), node.OuterXml);
                    element.Children.Add(text);
                }
                else
                {
                    //Single Child which is not a Text Node

                    //Recurse on the single Child Node
                    if (!this.IsIgnorableNode(node.ChildNodes[0]))
                    {
                        ElementEvent childEvent = this.GenerateEvents(context, node.ChildNodes[0], element);
                        element.Children.Add(childEvent);
                    }
                }
            }

            return element;
        }
        private IRdfXmlEvent GetElement()
        {
            //Generate Element Event
            ElementEvent el = new ElementEvent(this._reader.Name, this.GetBaseUri(), this._reader.Value, this.GetPosition());
            this._requireEndElement = this._reader.IsEmptyElement;

            //Read Attribute Events
            if (this._reader.HasAttributes)
            {
                for (int i = 0; i < this._reader.AttributeCount; i++)
                {
                    IRdfXmlEvent attr = this.GetNextAttribute();
                    if (attr is AttributeEvent)
                    {
                        el.Attributes.Add((AttributeEvent)attr);
                    }
                    else if (attr is NamespaceAttributeEvent)
                    {
                        el.NamespaceAttributes.Add((NamespaceAttributeEvent)attr);
                    }
                    else if (attr is LanguageAttributeEvent)
                    {
                        el.Language = ((LanguageAttributeEvent)attr).Language;
                    }
                    else if (attr is ParseTypeAttributeEvent)
                    {
                        el.ParseType = ((ParseTypeAttributeEvent)attr).ParseType;
                        el.Attributes.Add(new AttributeEvent(this._reader.Name, this._reader.Value, this._reader.Value, this.GetPosition()));
                    }
                    else if (attr is XmlBaseAttributeEvent)
                    {
                        el.BaseUri = ((XmlBaseAttributeEvent)attr).BaseUri;
                        this._currentBaseUri = el.BaseUri;
                    }
                }
            }

            //Validate generated Attributes for Namespace Confusion and URIRef encoding
            foreach (AttributeEvent a in el.Attributes)
            {
                //Namespace Confusion should only apply to Attributes without a Namespace specified
                if (a.Namespace.Equals(String.Empty))
                {
                    if (RdfXmlSpecsHelper.IsAmbigiousAttributeName(a.LocalName))
                    {
                        //Can't use any of the RDF terms that mandate the rdf: prefix without it
                        throw new RdfParseException("An Attribute with an ambigious name '" + a.LocalName + "' was encountered.  The following attribute names MUST have the rdf: prefix - about, aboutEach, ID, bagID, type, resource, parseType");
                    }
                }

                //URIRef encoding check
                if (!RdfXmlSpecsHelper.IsValidUriRefEncoding(a.Value))
                {
                    throw new RdfParseException("An Attribute with an incorrectly encoded URIRef was encountered, URIRef's must be encoded in Unicode Normal Form C");
                }
            }

            return el;
        }
        /// <summary>
        /// Given an XML Node that is the Root of the RDF/XML section of the Document Tree creates the RootEvent and generates the rest of the Event Tree by recursive calls to the <see cref="GenerateEvents">GenerateEvents</see> method
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="docEl">XML Node that is the Root of the RDF/XML section of the Document Tree</param>
        /// <returns></returns>
        private RootEvent GenerateEventTree(RdfXmlParserContext context, XmlNode docEl)
        {
            //Get the Document Element
            //XmlNode docEl = document.DocumentElement;

            //Generate a Root Event and Element Event from it
            RootEvent root = new RootEvent(docEl.BaseURI, docEl.OuterXml);
            if (docEl.BaseURI.Equals(String.Empty))
            {
                if (context.BaseUri != null)
                {
                    root.BaseUri = context.BaseUri.ToString();
                }
            }
            ElementEvent element = new ElementEvent(docEl.LocalName, docEl.Prefix, root.BaseUri, docEl.OuterXml);

            //Initialise Language Settings
            root.Language = String.Empty;
            element.Language = root.Language;

            //Set as Document Element and add as only Child
            root.DocumentElement = element;
            root.Children.Add(element);

            #region Attribute Processing

            //Go through attributes looking for XML Namespace Declarations
            foreach (XmlAttribute attr in docEl.Attributes)
            {
                if (attr.Prefix.Equals("xmlns") || attr.Name == "xmlns")
                {
                    //Define a Namespace
                    String prefix = attr.LocalName;
                    if (prefix.Equals("xmlns")) prefix = String.Empty;
                    String uri;
                    if (attr.Value.StartsWith("http://"))
                    {
                        //Absolute Uri
                        uri = attr.Value;
                    }
                    else if (!root.BaseUri.Equals(String.Empty))
                    {
                        //Relative Uri with a Base Uri to resolve against
                        //uri = root.BaseUri + attr.Value;
                        uri = Tools.ResolveUri(attr.Value, root.BaseUri);
                    }
                    else
                    {
                        //Relative Uri with no Base Uri
                        throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI");
                    }
                    context.Namespaces.AddNamespace(prefix, new Uri(uri));
                }
                else if (attr.Name == "xml:base")
                {
                    //Set the Base Uri
                    String baseUri = attr.Value;

                    if (RdfXmlSpecsHelper.IsAbsoluteURI(baseUri))
                    {
                        //Absolute Uri
                        root.BaseUri = baseUri;
                    }
                    else if (!element.BaseUri.Equals(String.Empty))
                    {
                        //Relative Uri with a Base Uri to resolve against
                        //root.BaseUri += baseUri;
                        root.BaseUri = Tools.ResolveUri(baseUri, root.BaseUri);
                    }
                    else
                    {
                        //Relative Uri with no Base Uri
                        throw new RdfParseException("Cannot resolve a Relative Base URI since there is no in-scope Base URI");
                    }
                    element.BaseUri = root.BaseUri;
                }
            }

            #endregion

            //Iterate over Children
            foreach (XmlNode child in docEl.ChildNodes)
            {
                //Ignore Irrelevant Node Types
                if (this.IsIgnorableNode(child))
                {
                    continue;
                }

                //Generate an Event for the Child Node
                ElementEvent childEvent = this.GenerateEvents(context, child, element);
                element.Children.Add(childEvent);
            }

            //Return the Root Event
            return root;
        }
Пример #4
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");
            }

            //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);
            }
        }
Пример #5
0
 private IUriNode Resolve(RdfXmlParserContext context, ElementEvent el)
 {
     try
     {
         IUriNode u = context.Handler.CreateUriNode(new Uri(Tools.ResolveQName(el.QName, context.Namespaces, context.BaseUri)));
         return u;
     }
     catch (Exception ex)
     {
         throw ParserHelper.Error(ex.Message, el);
     }
 }
Пример #6
0
        //Useful Functions defined as part of the Grammar
        #region Useful Grammar Helper Functions

        /// <summary>
        /// Applies the Namespace Attributes of an Element Event to the Namespace Map
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="evt">Element Event</param>
        private void ApplyNamespaces(RdfXmlParserContext context, ElementEvent evt)
        {
            if (!evt.BaseUri.Equals(String.Empty))
            {
                Uri baseUri = new Uri(Tools.ResolveUri(evt.BaseUri, context.BaseUri.ToSafeString()));
                context.BaseUri = baseUri;
                if (!context.Handler.HandleBaseUri(baseUri)) ParserHelper.Stop();
            }
            foreach (NamespaceAttributeEvent ns in evt.NamespaceAttributes)
            {
                if (!context.Namespaces.HasNamespace(ns.Prefix) || !context.Namespaces.GetNamespaceUri(ns.Prefix).ToString().Equals(ns.Uri))
                {
                    context.Namespaces.AddNamespace(ns.Prefix, new Uri(ns.Uri));
                    if (!context.Handler.HandleNamespace(ns.Prefix, new Uri(ns.Uri))) ParserHelper.Stop();
                }
            }
        }
Пример #7
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 temp = new EventQueue();
                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(new Uri(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(new Uri(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);
                    }
                }
            }
        }
Пример #8
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 eventlist, IRdfXmlEvent parent)
        {
            //Tracing
            if (this._traceparsing)
            {
                this.ProductionTrace("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;

            //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 subEvents = new EventQueue();

                //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);
            }
        }