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