Esempio n. 1
0
        /// <summary>
        /// Generates Output for Nodes in Turtle syntax
        /// </summary>
        /// <param name="globalContext">Context for writing the Store</param>
        /// <param name="context">Context for writing the Graph</param>
        /// <param name="n">Node to generate output for</param>
        /// <param name="segment">Segment of the Triple being written</param>
        /// <returns></returns>
        private String GenerateNodeOutput(TriGWriterContext globalContext, TurtleWriterContext context, INode n, TripleSegment segment)
        {
            switch (n.NodeType)
            {
            case NodeType.Blank:
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("TriG"));
                }
                break;

            case NodeType.GraphLiteral:
                throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("TriG"));

            case NodeType.Literal:
                if (segment == TripleSegment.Subject)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("TriG"));
                }
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("TriG"));
                }
                break;

            case NodeType.Uri:
                break;

            default:
                throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("TriG"));
            }

            return(context.NodeFormatter.Format(n, segment));
        }
Esempio n. 2
0
        /// <summary>
        /// Converts a Node into relevant NTriples Syntax.
        /// </summary>
        /// <param name="n">Node to convert.</param>
        /// <param name="context">Writer Context.</param>
        /// <param name="segment">Triple Segment being written.</param>
        /// <returns></returns>
        private string NodeToNTriples(NTriplesWriterContext context, INode n, TripleSegment segment)
        {
            switch (n.NodeType)
            {
            case NodeType.Blank:
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("NQuads"));
                }
                break;

            case NodeType.Literal:
                if (segment == TripleSegment.Subject)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("NQuads"));
                }
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("NQuads"));
                }
                break;

            case NodeType.Uri:
                break;

            case NodeType.GraphLiteral:
                throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("NQuads"));

            default:
                throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("NQuads"));
            }

            return(context.NodeFormatter.Format(n));
        }
        /// <summary>
        /// Generates Output for Nodes in Turtle syntax
        /// </summary>
        /// <param name="context">Writer Context</param>
        /// <param name="n">Node to generate output for</param>
        /// <param name="segment">Segment of the Triple being written</param>
        /// <param name="indent">Indentation</param>
        /// <returns></returns>
        private String GenerateNodeOutput(CompressingTurtleWriterContext context, INode n, TripleSegment segment, int indent)
        {
            StringBuilder output = new StringBuilder();

            switch (n.NodeType)
            {
            case NodeType.Blank:
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("Turtle"));
                }

                if (context.Collections.ContainsKey(n))
                {
                    output.Append(this.GenerateCollectionOutput(context, context.Collections[n], indent));
                }
                else
                {
                    return(context.NodeFormatter.Format(n, segment));
                }
                break;

            case NodeType.GraphLiteral:
                throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("Turtle"));

            case NodeType.Literal:
                if (segment == TripleSegment.Subject)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("Turtle"));
                }
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("Turtle"));
                }
                return(context.NodeFormatter.Format(n, segment));

            case NodeType.Uri:
                return(context.NodeFormatter.Format(n, segment));

            default:
                throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("Turtle"));
            }

            return(output.ToString());
        }
        /// <summary>
        /// Generates Output for the given Node.
        /// </summary>
        /// <param name="context">Writer Context.</param>
        /// <param name="n">Node.</param>
        /// <param name="segment">Triple Segment.</param>
        private void GenerateNodeOutput(BaseWriterContext context, INode n, TripleSegment segment)
        {
            switch (n.NodeType)
            {
            case NodeType.Blank:
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("CSV"));
                }

                context.Output.Write(_formatter.Format(n));
                break;

            case NodeType.GraphLiteral:
                throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("CSV"));

            case NodeType.Literal:
                if (segment == TripleSegment.Subject)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("CSV"));
                }
                if (segment == TripleSegment.Predicate)
                {
                    throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("CSV"));
                }

                context.Output.Write(_formatter.Format(n));
                break;

            case NodeType.Uri:
                context.Output.Write(_formatter.Format(n));
                break;

            default:
                throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("CSV"));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Internal method which generates the RDF/Json Output for a Graph
        /// </summary>
        /// <param name="g">Graph to save</param>
        /// <param name="output">Stream to save to</param>
        private void GenerateOutput(IGraph g, TextWriter output)
        {
            // Always force RDF Namespace to be correctly defined
            g.NamespaceMap.Import(this._defaultNamespaces);
            g.NamespaceMap.AddNamespace("rdf", UriFactory.Create(NamespaceMapper.RDF));

            // Create our Writer Context and start the XML Document
            RdfXmlWriterContext context = new RdfXmlWriterContext(g, output);

            context.CompressionLevel = this._compressionLevel;
            context.UseDtd           = this._useDTD;
            context.Writer.WriteStartDocument();

            if (context.UseDtd)
            {
                // Create the DOCTYPE declaration
                StringBuilder entities = new StringBuilder();
                String        uri;
                entities.Append('\n');
                foreach (String prefix in context.NamespaceMap.Prefixes)
                {
                    uri = context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri;
                    if (!uri.Equals(context.NamespaceMap.GetNamespaceUri(prefix).ToString()))
                    {
                        context.UseDtd = false;
                        break;
                    }
                    if (!prefix.Equals(String.Empty))
                    {
                        entities.AppendLine("\t<!ENTITY " + prefix + " '" + uri + "'>");
                    }
                }
                if (context.UseDtd)
                {
                    context.Writer.WriteDocType("rdf:RDF", null, null, entities.ToString());
                }
            }

            // Create the rdf:RDF element
            context.Writer.WriteStartElement("rdf", "RDF", NamespaceMapper.RDF);
            if (context.Graph.BaseUri != null)
            {
                context.Writer.WriteAttributeString("xml", "base", null, context.Graph.BaseUri.AbsoluteUri);//Uri.EscapeUriString(context.Graph.BaseUri.ToString()));
            }
            context.NamespaceMap.IncrementNesting();
            foreach (String prefix in context.NamespaceMap.Prefixes)
            {
                if (prefix.Equals("rdf"))
                {
                    continue;
                }

                if (!prefix.Equals(String.Empty))
                {
                    context.Writer.WriteStartAttribute("xmlns", prefix, null);
                    // String nsRef = "&" + prefix + ";";
                    // context.Writer.WriteRaw(nsRef);
                    // context.Writer.WriteEntityRef(prefix);
                    context.Writer.WriteRaw(WriterHelper.EncodeForXml(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri));//Uri.EscapeUriString(WriterHelper.EncodeForXml(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri)));
                    context.Writer.WriteEndAttribute();
                }
                else
                {
                    context.Writer.WriteStartAttribute("xmlns");
                    context.Writer.WriteRaw(WriterHelper.EncodeForXml(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri));//Uri.EscapeUriString(WriterHelper.EncodeForXml(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri)));
                    context.Writer.WriteEndAttribute();
                }
            }

            // Find the Collections and Type References
            if (context.CompressionLevel >= WriterCompressionLevel.More)
            {
                WriterHelper.FindCollections(context, CollectionSearchMode.ImplicitOnly);
                // WriterHelper.FindCollections(context, CollectionSearchMode.All);
            }
            Dictionary <INode, String> typerefs = this.FindTypeReferences(context);

            // Get the Triples as a Sorted List
            List <Triple> ts = context.Graph.Triples.Where(t => !context.TriplesDone.Contains(t)).ToList();

            ts.Sort(new RdfXmlTripleComparer());

            // Variables we need to track our writing
            INode lastSubj, lastPred, lastObj;

            lastSubj = lastPred = lastObj = null;

            for (int i = 0; i < ts.Count; i++)
            {
                Triple t = ts[i];
                if (context.TriplesDone.Contains(t))
                {
                    continue;                                  //Skip if already done
                }
                if (lastSubj == null || !t.Subject.Equals(lastSubj))
                {
                    // Start a new set of Triples
                    if (lastSubj != null)
                    {
                        context.NamespaceMap.DecrementNesting();
                        context.Writer.WriteEndElement();
                    }
                    if (lastPred != null)
                    {
                        context.NamespaceMap.DecrementNesting();
                        context.Writer.WriteEndElement();
                    }

                    // Write out the Subject
                    // Validate Subject
                    // Use a Type Reference if applicable
                    context.NamespaceMap.IncrementNesting();
                    if (typerefs.ContainsKey(t.Subject))
                    {
                        String tref = typerefs[t.Subject];
                        if (tref.StartsWith(":"))
                        {
                            context.Writer.WriteStartElement(tref.Substring(1));
                        }
                        else if (tref.Contains(":"))
                        {
                            context.Writer.WriteStartElement(tref.Substring(0, tref.IndexOf(':')), tref.Substring(tref.IndexOf(':') + 1), null);
                        }
                        else
                        {
                            context.Writer.WriteStartElement(tref);
                        }
                    }
                    else
                    {
                        context.Writer.WriteStartElement("rdf", "Description", NamespaceMapper.RDF);
                    }
                    lastSubj = t.Subject;

                    // Apply appropriate attributes
                    switch (t.Subject.NodeType)
                    {
                    case NodeType.GraphLiteral:
                        throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML"));

                    case NodeType.Literal:
                        throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("RDF/XML"));

                    case NodeType.Blank:
                        if (context.Collections.ContainsKey(t.Subject))
                        {
                            this.GenerateCollectionOutput(context, t.Subject);
                        }
                        else
                        {
                            context.Writer.WriteAttributeString("rdf", "nodeID", null, context.BlankNodeMapper.GetOutputID(((IBlankNode)t.Subject).InternalID));
                        }
                        break;

                    case NodeType.Uri:
                        this.GenerateUriOutput(context, (IUriNode)t.Subject, "rdf:about");
                        break;

                    default:
                        throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/XML"));
                    }

                    // Write the Predicate
                    context.NamespaceMap.IncrementNesting();
                    this.GeneratePredicateNode(context, t.Predicate);
                    lastPred = t.Predicate;
                    lastObj  = null;
                }
                else if (lastPred == null || !t.Predicate.Equals(lastPred))
                {
                    if (lastPred != null)
                    {
                        context.NamespaceMap.DecrementNesting();
                        context.Writer.WriteEndElement();
                    }

                    // Write the Predicate
                    context.NamespaceMap.IncrementNesting();
                    this.GeneratePredicateNode(context, t.Predicate);
                    lastPred = t.Predicate;
                    lastObj  = null;
                }

                // Write the Object
                if (lastObj != null)
                {
                    // Terminate the previous Predicate Node
                    context.NamespaceMap.DecrementNesting();
                    context.Writer.WriteEndElement();

                    // Start a new Predicate Node
                    context.NamespaceMap.DecrementNesting();
                    context.Writer.WriteEndElement();
                    context.NamespaceMap.IncrementNesting();
                    this.GeneratePredicateNode(context, t.Predicate);
                }
                // Create an Object for the Object
                switch (t.Object.NodeType)
                {
                case NodeType.Blank:
                    if (context.Collections.ContainsKey(t.Object))
                    {
                        // Output a Collection
                        this.GenerateCollectionOutput(context, t.Object);
                    }
                    else
                    {
                        // Terminate the Blank Node triple by adding a rdf:nodeID attribute
                        context.Writer.WriteAttributeString("rdf", "nodeID", null, context.BlankNodeMapper.GetOutputID(((IBlankNode)t.Object).InternalID));
                    }

                    break;

                case NodeType.GraphLiteral:
                    throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML"));

                case NodeType.Literal:
                    ILiteralNode lit = (ILiteralNode)t.Object;
                    this.GenerateLiteralOutput(context, lit);

                    break;

                case NodeType.Uri:
                    this.GenerateUriOutput(context, (IUriNode)t.Object, "rdf:resource");
                    break;

                default:
                    throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/XML"));
                }
                lastObj = t.Object;

                // Force a new Predicate Node
                context.NamespaceMap.DecrementNesting();
                context.Writer.WriteEndElement();
                lastPred = null;

                context.TriplesDone.Add(t);
            }

            // Check we haven't failed to output any collections
            foreach (KeyValuePair <INode, OutputRdfCollection> pair in context.Collections)
            {
                if (pair.Value.Triples.Count > 0)
                {
                    if (typerefs.ContainsKey(pair.Key))
                    {
                        String tref = typerefs[pair.Key];
                        context.NamespaceMap.IncrementNesting();
                        if (tref.StartsWith(":"))
                        {
                            context.Writer.WriteStartElement(tref.Substring(1));
                        }
                        else if (tref.Contains(":"))
                        {
                            context.Writer.WriteStartElement(tref.Substring(0, tref.IndexOf(':')), tref.Substring(tref.IndexOf(':') + 1), null);
                        }
                        else
                        {
                            context.Writer.WriteStartElement(tref);
                        }

                        this.GenerateCollectionOutput(context, pair.Key);

                        context.Writer.WriteEndElement();
                    }
                    else
                    {
                        context.Writer.WriteStartElement("rdf", "Description", NamespaceMapper.RDF);
                        context.Writer.WriteAttributeString("rdf", "nodeID", NamespaceMapper.RDF, context.BlankNodeMapper.GetOutputID(((IBlankNode)pair.Key).InternalID));
                        this.GenerateCollectionOutput(context, pair.Key);
                        context.Writer.WriteEndElement();
                        // throw new RdfOutputException("Failed to output a Collection due to an unknown error");
                    }
                }
            }

            context.NamespaceMap.DecrementNesting();
            context.Writer.WriteEndDocument();

            // Save to the Output Stream
            context.Writer.Flush();
        }
Esempio n. 6
0
        /// <summary>
        /// Internal method which generates the RDF/Json Output for a Graph.
        /// </summary>
        /// <param name="g">Graph to save.</param>
        /// <param name="output">Stream to save to.</param>
        private void GenerateOutput(IGraph g, TextWriter output)
        {
            // Get a Blank Node Output Mapper
            BlankNodeOutputMapper bnodeMapper = new BlankNodeOutputMapper(WriterHelper.IsValidBlankNodeID);

            // Get the Writer and Configure Options
            JsonTextWriter writer = new JsonTextWriter(output);

            if (_prettyprint)
            {
                writer.Formatting = Newtonsoft.Json.Formatting.Indented;
            }
            else
            {
                writer.Formatting = Newtonsoft.Json.Formatting.None;
            }

            // Start the overall Object which represents the Graph
            writer.WriteStartObject();

            // Get the Triples as a Sorted List
            List <Triple> ts = g.Triples.ToList();

            ts.Sort(new FullTripleComparer(new FastNodeComparer()));

            // Variables we need to track our writing
            INode lastSubj, lastPred;

            lastSubj = lastPred = null;

            for (int i = 0; i < ts.Count; i++)
            {
                Triple t = ts[i];
                if (lastSubj == null || !t.Subject.Equals(lastSubj))
                {
                    // Terminate previous Triples
                    if (lastSubj != null)
                    {
                        writer.WriteEndArray();
                        writer.WriteEndObject();
                    }

                    // Start a new set of Triples
                    // Validate Subject
                    switch (t.Subject.NodeType)
                    {
                    case NodeType.GraphLiteral:
                        throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/JSON"));

                    case NodeType.Literal:
                        throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("RDF/JSON"));

                    case NodeType.Blank:
                        break;

                    case NodeType.Uri:
                        // OK
                        break;

                    default:
                        throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/JSON"));
                    }

                    // Write out the Subject
                    if (t.Subject.NodeType != NodeType.Blank)
                    {
                        writer.WritePropertyName(t.Subject.ToString());
                    }
                    else
                    {
                        // Remap Blank Node IDs as appropriate
                        writer.WritePropertyName("_:" + bnodeMapper.GetOutputID(((IBlankNode)t.Subject).InternalID));
                    }

                    // Start an Object for the Subject
                    writer.WriteStartObject();

                    lastSubj = t.Subject;

                    // Write the first Predicate
                    // Validate Predicate
                    switch (t.Predicate.NodeType)
                    {
                    case NodeType.GraphLiteral:
                        throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/JSON"));

                    case NodeType.Blank:
                        throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("RDF/JSON"));

                    case NodeType.Literal:
                        throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("RDF/JSON"));

                    case NodeType.Uri:
                        // OK
                        break;

                    default:
                        throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/JSON"));
                    }

                    // Write the Predicate
                    writer.WritePropertyName(t.Predicate.ToString());

                    // Create an Array for the Objects
                    writer.WriteStartArray();

                    lastPred = t.Predicate;
                }
                else if (lastPred == null || !t.Predicate.Equals(lastPred))
                {
                    // Terminate previous Predicate Object list
                    writer.WriteEndArray();

                    // Write the next Predicate
                    // Validate Predicate
                    switch (t.Predicate.NodeType)
                    {
                    case NodeType.GraphLiteral:
                        throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/JSON"));

                    case NodeType.Blank:
                        throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("RDF/JSON"));

                    case NodeType.Literal:
                        throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("RDF/JSON"));

                    case NodeType.Uri:
                        // OK
                        break;

                    default:
                        throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/JSON"));
                    }

                    // Write the Predicate
                    writer.WritePropertyName(t.Predicate.ToString());

                    // Create an Array for the Objects
                    writer.WriteStartArray();

                    lastPred = t.Predicate;
                }

                // Write the Object
                // Create an Object for the Object
                INode obj = t.Object;
                writer.WriteStartObject();
                writer.WritePropertyName("value");
                switch (obj.NodeType)
                {
                case NodeType.Blank:
                    // Remap Blank Node IDs as appropriate
                    writer.WriteValue("_:" + bnodeMapper.GetOutputID(((IBlankNode)obj).InternalID));
                    writer.WritePropertyName("type");
                    writer.WriteValue("bnode");
                    break;

                case NodeType.GraphLiteral:
                    throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/JSON"));

                case NodeType.Literal:
                    ILiteralNode lit = (ILiteralNode)obj;
                    writer.WriteValue(lit.Value);

                    if (!lit.Language.Equals(String.Empty))
                    {
                        writer.WritePropertyName("lang");
                        writer.WriteValue(lit.Language);
                    }
                    else if (lit.DataType != null)
                    {
                        writer.WritePropertyName("datatype");
                        writer.WriteValue(lit.DataType.AbsoluteUri);
                    }
                    writer.WritePropertyName("type");
                    writer.WriteValue("literal");
                    break;

                case NodeType.Uri:
                    writer.WriteValue(obj.ToString());
                    writer.WritePropertyName("type");
                    writer.WriteValue("uri");
                    break;

                default:
                    throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/JSON"));
                }
                writer.WriteEndObject();
            }

            // Terminate the Object which represents the Graph
            writer.WriteEndObject();
        }
Esempio n. 7
0
        /// <summary>
        /// Internal method which generates the RDF/Json Output for a Graph
        /// </summary>
        /// <param name="context">Writer Context</param>
        private void GenerateOutput(RdfXmlWriterContext context)
        {
            context.UseDtd = this._useDTD;

            //Create required variables
            int           nextNamespaceID = 0;
            List <String> tempNamespaces  = new List <String>();

            //Always force RDF Namespace to be correctly defined
            context.Graph.NamespaceMap.AddNamespace("rdf", new Uri(NamespaceMapper.RDF));

            //Create an XML Document
            XmlDocument    doc  = new XmlDocument();
            XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null);

            doc.AppendChild(decl);

            //Create the DOCTYPE declaration and the rdf:RDF element
            StringBuilder entities = new StringBuilder();
            XmlElement    rdf      = doc.CreateElement("rdf:RDF", NamespaceMapper.RDF);

            if (context.Graph.BaseUri != null)
            {
                XmlAttribute baseUri = doc.CreateAttribute("xml:base");
                baseUri.Value = Uri.EscapeUriString(context.Graph.BaseUri.ToString());
                rdf.Attributes.Append(baseUri);
            }

            XmlAttribute ns;
            String       uri;

            entities.Append('\n');
            foreach (String prefix in context.Graph.NamespaceMap.Prefixes)
            {
                uri = context.Graph.NamespaceMap.GetNamespaceUri(prefix).ToString();
                if (!prefix.Equals(String.Empty))
                {
                    entities.AppendLine("\t<!ENTITY " + prefix + " '" + uri + "'>");
                    ns       = doc.CreateAttribute("xmlns:" + prefix);
                    ns.Value = Uri.EscapeUriString(uri.Replace("'", "&apos;"));
                }
                else
                {
                    ns       = doc.CreateAttribute("xmlns");
                    ns.Value = Uri.EscapeUriString(uri);
                }
                rdf.Attributes.Append(ns);
            }
            if (context.UseDtd)
            {
                XmlDocumentType doctype = doc.CreateDocumentType("rdf:RDF", null, null, entities.ToString());
                doc.AppendChild(doctype);
            }
            doc.AppendChild(rdf);

            //Find the Collections
            if (this._compressionLevel >= WriterCompressionLevel.More)
            {
                WriterHelper.FindCollections(context);
            }

            //Find the Type References
            Dictionary <INode, String> typerefs = this.FindTypeReferences(context, ref nextNamespaceID, tempNamespaces, doc);

            //Get the Triples as a Sorted List
            List <Triple> ts = context.Graph.Triples.Where(t => !context.TriplesDone.Contains(t)).ToList();

            ts.Sort();

            //Variables we need to track our writing
            INode lastSubj, lastPred;

            lastSubj = lastPred = null;
            XmlElement subj, pred;

            //Initialise stuff to keep the compiler happy
            subj = doc.CreateElement("rdf:Description", NamespaceMapper.RDF);
            pred = doc.CreateElement("temp");

            for (int i = 0; i < ts.Count; i++)
            {
                Triple t = ts[i];
                if (context.TriplesDone.Contains(t))
                {
                    continue;                                  //Skip if already done
                }
                if (lastSubj == null || !t.Subject.Equals(lastSubj))
                {
                    //Start a new set of Triples
                    //Validate Subject
                    //Use a Type Reference if applicable
                    if (typerefs.ContainsKey(t.Subject))
                    {
                        String tref = typerefs[t.Subject];
                        String tprefix;
                        if (tref.StartsWith(":"))
                        {
                            tprefix = String.Empty;
                        }
                        else if (tref.Contains(":"))
                        {
                            tprefix = tref.Substring(0, tref.IndexOf(':'));
                        }
                        else
                        {
                            tprefix = String.Empty;
                        }
                        subj = doc.CreateElement(tref, context.Graph.NamespaceMap.GetNamespaceUri(tprefix).ToString());
                    }
                    else
                    {
                        subj = doc.CreateElement("rdf:Description", NamespaceMapper.RDF);
                    }

                    //Write out the Subject
                    doc.DocumentElement.AppendChild(subj);
                    lastSubj = t.Subject;

                    //Apply appropriate attributes
                    switch (t.Subject.NodeType)
                    {
                    case NodeType.GraphLiteral:
                        throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML"));

                    case NodeType.Literal:
                        throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("RDF/XML"));

                    case NodeType.Blank:
                        if (context.Collections.ContainsKey(t.Subject))
                        {
                            this.GenerateCollectionOutput(context, t.Subject, subj, ref nextNamespaceID, tempNamespaces, doc);
                        }
                        else
                        {
                            XmlAttribute nodeID = doc.CreateAttribute("rdf:nodeID", NamespaceMapper.RDF);
                            nodeID.Value = ((IBlankNode)t.Subject).InternalID;
                            subj.Attributes.Append(nodeID);
                        }
                        break;

                    case NodeType.Uri:
                        this.GenerateUriOutput(context, (IUriNode)t.Subject, "rdf:about", tempNamespaces, subj, doc);
                        break;

                    default:
                        throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/XML"));
                    }

                    //Write the Predicate
                    pred = this.GeneratePredicateNode(context, t.Predicate, ref nextNamespaceID, tempNamespaces, doc, subj);
                    subj.AppendChild(pred);
                    lastPred = t.Predicate;
                }
                else if (lastPred == null || !t.Predicate.Equals(lastPred))
                {
                    //Write the Predicate
                    pred = this.GeneratePredicateNode(context, t.Predicate, ref nextNamespaceID, tempNamespaces, doc, subj);
                    subj.AppendChild(pred);
                    lastPred = t.Predicate;
                }

                //Write the Object
                //Create an Object for the Object
                switch (t.Object.NodeType)
                {
                case NodeType.Blank:
                    if (pred.HasChildNodes || pred.HasAttributes)
                    {
                        //Require a new Predicate
                        pred = this.GeneratePredicateNode(context, t.Predicate, ref nextNamespaceID, tempNamespaces, doc, subj);
                        subj.AppendChild(pred);
                    }

                    if (context.Collections.ContainsKey(t.Object))
                    {
                        //Output a Collection
                        this.GenerateCollectionOutput(context, t.Object, pred, ref nextNamespaceID, tempNamespaces, doc);
                    }
                    else
                    {
                        //Terminate the Blank Node triple by adding a rdf:nodeID attribute
                        XmlAttribute nodeID = doc.CreateAttribute("rdf:nodeID", NamespaceMapper.RDF);
                        nodeID.Value = ((IBlankNode)t.Object).InternalID;
                        pred.Attributes.Append(nodeID);
                    }

                    //Force a new Predicate after Blank Nodes
                    lastPred = null;

                    break;

                case NodeType.GraphLiteral:
                    throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML"));

                case NodeType.Literal:
                    ILiteralNode lit = (ILiteralNode)t.Object;

                    if (pred.HasChildNodes || pred.HasAttributes)
                    {
                        //Require a new Predicate
                        pred = this.GeneratePredicateNode(context, t.Predicate, ref nextNamespaceID, tempNamespaces, doc, subj);
                        subj.AppendChild(pred);
                    }

                    this.GenerateLiteralOutput(context, lit, pred, doc);

                    //Force a new Predicate Node after Literals
                    lastPred = null;

                    break;

                case NodeType.Uri:

                    this.GenerateUriOutput(context, (IUriNode)t.Object, "rdf:resource", tempNamespaces, pred, doc);

                    //Force a new Predicate Node after URIs
                    lastPred = null;

                    break;

                default:
                    throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("RDF/XML"));
                }

                context.TriplesDone.Add(t);
            }

            //Check we haven't failed to output any collections
            foreach (KeyValuePair <INode, OutputRdfCollection> pair in context.Collections)
            {
                if (!pair.Value.HasBeenWritten)
                {
                    if (typerefs.ContainsKey(pair.Key))
                    {
                        String tref = typerefs[pair.Key];
                        String tprefix;
                        if (tref.StartsWith(":"))
                        {
                            tref    = tref.Substring(1);
                            tprefix = String.Empty;
                        }
                        else if (tref.Contains(":"))
                        {
                            tprefix = tref.Substring(0, tref.IndexOf(':'));
                        }
                        else
                        {
                            tprefix = String.Empty;
                        }
                        subj = doc.CreateElement(tref, context.Graph.NamespaceMap.GetNamespaceUri(tprefix).ToString());

                        doc.DocumentElement.AppendChild(subj);

                        this.GenerateCollectionOutput(context, pair.Key, subj, ref nextNamespaceID, tempNamespaces, doc);
                    }
                    else
                    {
                        //Generate an rdf:Description Node with a rdf:nodeID on it
                        XmlElement   colNode = doc.CreateElement("rdf:Description");
                        XmlAttribute nodeID  = doc.CreateAttribute("rdf:nodeID");
                        nodeID.Value = ((IBlankNode)pair.Key).InternalID;
                        colNode.Attributes.Append(nodeID);
                        doc.DocumentElement.AppendChild(colNode);
                        this.GenerateCollectionOutput(context, pair.Key, colNode, ref nextNamespaceID, tempNamespaces, doc);
                        //throw new RdfOutputException("Failed to output a Collection due to an unknown error");
                    }
                }
            }

            //Save to the Output Stream
            InternalXmlWriter writer = new InternalXmlWriter();

            writer.Save(context.Output, doc);

            //Get rid of the Temporary Namespace
            foreach (String tempPrefix in tempNamespaces)
            {
                context.Graph.NamespaceMap.RemoveNamespace(tempPrefix);
            }
        }