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