/// <summary> /// Gets the next event from the XML stream /// </summary> /// <returns></returns> public IRdfXmlEvent GetNextEvent() { if (_stop) { return(null); } // If the Root Element is filled then return it if (_rootEl != null) { IRdfXmlEvent temp = _rootEl; _rootEl = null; return(temp); } // If Literal Parsing flag is set then we've just read an element which had rdf:parseType="Literal" if (_parseLiteral) { _requireEndElement = true; _parseLiteral = false; _noRead = true; _reader.MoveToContent(); String data = _reader.ReadInnerXml(); return(new TypedLiteralEvent(data, RdfSpecsHelper.RdfXmlLiteral, data, GetPosition())); } // If we need to return an end element then do so if (_requireEndElement) { _requireEndElement = false; _currentBaseUri = _baseUris.Pop(); return(new EndElementEvent(GetPosition())); } // If at EOF throw an error if (_reader.EOF) { throw new RdfParseException("Unable to read further events as the end of the stream has already been reached"); } // Otherwise attempt to read the next node bool read = true; if (!_noRead) { read = _reader.Read(); } else { _noRead = false; } if (read) { // Return the appropriate event for the Node Type switch (_reader.NodeType) { case XmlNodeType.Element: // Element if (_first) { _first = false; _rdfRootSeen = IsName("RDF", NamespaceMapper.RDF); _rootEl = GetElement(); RootEvent root = new RootEvent(GetBaseUri(), _reader.Value, GetPosition()); root.DocumentElement = (ElementEvent)_rootEl; root.Children.Add((ElementEvent)_rootEl); if (root.BaseUri.Equals(String.Empty)) { root.BaseUri = _currentBaseUri; } return(root); } else { if (!_first && IsName("RDF", NamespaceMapper.RDF)) { if (_rdfRootSeen) { throw new RdfParseException("Unexpected nested rdf:RDF node encountered, this is not valid RDF/XML syntax"); } _noRead = true; _first = true; return(new ClearQueueEvent()); } return(GetElement()); } case XmlNodeType.EndElement: // End of an Element _currentBaseUri = _baseUris.Pop(); if (IsName("RDF", NamespaceMapper.RDF)) { _stop = true; } return(new EndElementEvent(GetPosition())); case XmlNodeType.Attribute: // Attribute throw new RdfParseException("Unexpected Attribute Node encountered"); case XmlNodeType.Text: return(new TextEvent(_reader.Value, _reader.Value, GetPosition())); case XmlNodeType.CDATA: return(new TextEvent(_reader.Value, _reader.Value, GetPosition())); case XmlNodeType.Document: case XmlNodeType.DocumentType: case XmlNodeType.XmlDeclaration: case XmlNodeType.Comment: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Notation: case XmlNodeType.Whitespace: // Node Types that don't generate events and just indicate to continue reading return(GetNextEvent()); default: throw new RdfParseException("Unexpected XML Node Type " + _reader.NodeType.ToString() + " encountered"); } } else { return(null); } }
/// <summary> /// Gets the next event from the XML stream /// </summary> /// <returns></returns> public IRdfXmlEvent GetNextEvent() { if (this._stop) return null; //If the Root Element is filled then return it if (this._rootEl != null) { IRdfXmlEvent temp = this._rootEl; this._rootEl = null; return temp; } //If Literal Parsing flag is set then we've just read an element which had rdf:parseType="Literal" if (this._parseLiteral) { this._requireEndElement = true; this._parseLiteral = false; this._noRead = true; this._reader.MoveToContent(); String data = this._reader.ReadInnerXml(); return new TypedLiteralEvent(data, RdfSpecsHelper.RdfXmlLiteral, data, this.GetPosition()); } //If we need to return an end element then do so if (this._requireEndElement) { this._requireEndElement = false; this._currentBaseUri = this._baseUris.Pop(); return new EndElementEvent(this.GetPosition()); } //If at EOF throw an error if (this._reader.EOF) throw new RdfParseException("Unable to read further events as the end of the stream has already been reached"); //Otherwise attempt to read the next node bool read = true; if (!this._noRead) { read = this._reader.Read(); } else { this._noRead = false; } if (read) { //Return the appropriate event for the Node Type switch (this._reader.NodeType) { case XmlNodeType.Element: //Element if (this._first) { this._first = false; this._rdfRootSeen = this.IsName("RDF", NamespaceMapper.RDF); this._rootEl = this.GetElement(); RootEvent root = new RootEvent(this.GetBaseUri(), this._reader.Value, this.GetPosition()); root.DocumentElement = (ElementEvent)this._rootEl; root.Children.Add((ElementEvent)this._rootEl); return root; } else { if (!this._first && this.IsName("RDF", NamespaceMapper.RDF)) { if (this._rdfRootSeen) throw new RdfParseException("Unexpected nested rdf:RDF node encountered, this is not valid RDF/XML syntax"); this._noRead = true; this._first = true; return new ClearQueueEvent(); } return this.GetElement(); } case XmlNodeType.EndElement: //End of an Element this._currentBaseUri = this._baseUris.Pop(); if (this.IsName("RDF", NamespaceMapper.RDF)) { this._stop = true; } return new EndElementEvent(this.GetPosition()); case XmlNodeType.Attribute: //Attribute throw new RdfParseException("Unexpected Attribute Node encountered"); case XmlNodeType.Text: return new TextEvent(this._reader.Value, this._reader.Value, this.GetPosition()); case XmlNodeType.CDATA: return new TextEvent(this._reader.Value, this._reader.Value, this.GetPosition()); case XmlNodeType.Document: case XmlNodeType.DocumentType: case XmlNodeType.XmlDeclaration: case XmlNodeType.Comment: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Notation: case XmlNodeType.Whitespace: //Node Types that don't generate events and just indicate to continue reading return this.GetNextEvent(); default: throw new RdfParseException("Unexpected XML Node Type " + this._reader.NodeType.ToString() + " encountered"); } } else { return null; } }
/// <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.AbsoluteUri; } } 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, UriFactory.Create(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 (IsIgnorableNode(child)) { continue; } // Generate an Event for the Child Node ElementEvent childEvent = GenerateEvents(context, child, element); element.Children.Add(childEvent); } // Return the Root Event return(root); }
/// <summary> /// Takes the Event Tree and Flattens it into a Queue as per the rules laid out in the RDF/XML Specification /// </summary> /// <param name="context">Parser Context</param> /// <param name="evt">Event which is the Root of the Tree (not necessarily a RootEvent)</param> /// <param name="nesting">A numeric value used for Parser Tracing to indicate nesting levels of the Event Tree</param> private void FlattenEventTree(RdfXmlParserContext context, IRdfXmlEvent evt, int nesting) { // Add to Queue context.Events.Enqueue(evt); if (context.TraceParsing) { Console.Write(nesting + " " + evt.GetType().ToString()); } // Iterate over Children where present if (evt is RootEvent) { RootEvent root = (RootEvent)evt; if (context.TraceParsing) { Console.WriteLine(""); } foreach (IRdfXmlEvent childEvent in root.Children) { FlattenEventTree(context, childEvent, nesting + 1); } // No End after a RootEvent return; } else if (evt is ElementEvent) { ElementEvent element = (ElementEvent)evt; if (context.TraceParsing) { Console.WriteLine(" " + element.Namespace + ":" + element.LocalName); } if (element.Children.Count > 0) { foreach (IRdfXmlEvent childEvent in element.Children) { FlattenEventTree(context, childEvent, nesting + 1); } } } else if (evt is TextEvent) { TextEvent text = (TextEvent)evt; if (context.TraceParsing) { Console.WriteLine(" " + text.Value); } // No additional End after a Text Event return; } else if (evt is TypedLiteralEvent) { TypedLiteralEvent tlit = (TypedLiteralEvent)evt; if (context.TraceParsing) { Console.WriteLine(); } // No additional End after a Text Event return; } // Add an End Element Event to the Queue EndElementEvent end = new EndElementEvent(); context.Events.Enqueue(end); if (context.TraceParsing) { String endDescrip = String.Empty; if (evt is ElementEvent) { ElementEvent temp = (ElementEvent)evt; endDescrip = " " + temp.QName; } Console.WriteLine(nesting + " " + end.GetType().ToString() + endDescrip); } }
/// <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; }