private void GeneratePredicateOutput(RdfXmlWriterContext context, Triple t) { context.NamespaceMap.IncrementNesting(); // Must ensure a URI predicate switch (t.Predicate.NodeType) { case NodeType.Blank: throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("RDF/XML")); case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML")); case NodeType.Literal: throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("RDF/XML")); case NodeType.Variable: throw new RdfOutputException(WriterErrorMessages.VariableNodesUnserializable("RDF/XML")); } IUriNode p = (IUriNode)t.Predicate; // First generate the Predicate Node UriRefType outType; String uriref = GenerateUriRef(context, p.Uri, UriRefType.QName, out outType); String tempPrefix = null, tempUri = null; if (outType != UriRefType.QName) { // Need to generate a temporary namespace GenerateTemporaryNamespace(context, p, out tempPrefix, out tempUri); uriref = GenerateUriRef(context, p.Uri, UriRefType.QName, out outType); if (outType != UriRefType.QName) { throw new RdfOutputException(WriterErrorMessages.UnreducablePropertyURIUnserializable + " - '" + p.Uri + "'"); } } // Use the QName for the Node if (uriref.Contains(':')) { // Create an element in the appropriate namespace String ns = context.NamespaceMap.GetNamespaceUri(uriref.Substring(0, uriref.IndexOf(':'))).AbsoluteUri; context.Writer.WriteStartElement(uriref.Substring(0, uriref.IndexOf(':')), uriref.Substring(uriref.IndexOf(':') + 1), ns); } else { // Create an element in the default namespace context.Writer.WriteStartElement(uriref); } if (tempPrefix != null && tempUri != null) { context.Writer.WriteAttributeString("xmlns", tempPrefix, null, Uri.EscapeUriString(tempUri)); } // Then generate the Object Output GenerateObjectOutput(context, t); context.Writer.WriteEndElement(); context.NamespaceMap.DecrementNesting(); }
private void GenerateObjectOutput(RdfXmlWriterContext context, Triple t) { // Take different actions depending on the Node Type to be written switch (t.Object.NodeType) { case NodeType.Blank: if (context.Collections.ContainsKey(t.Object)) { // Blank Node has a collection associated with it GenerateCollectionOutput(context, t.Object); } else { // Isolated Blank Node so use nodeID context.Writer.WriteAttributeString("rdf", "nodeID", NamespaceMapper.RDF, context.BlankNodeMapper.GetOutputID(((IBlankNode)t.Object).InternalID)); } break; case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML")); case NodeType.Literal: // Write as content of the current element ILiteralNode lit = (ILiteralNode)t.Object; if (lit.DataType != null) { if (lit.DataType.AbsoluteUri.Equals(RdfSpecsHelper.RdfXmlLiteral)) { // XML Literal context.Writer.WriteAttributeString("rdf", "parseType", NamespaceMapper.RDF, "Literal"); context.Writer.WriteRaw(lit.Value); } else { // Datatyped Literal context.Writer.WriteAttributeString("rdf", "datatype", NamespaceMapper.RDF, lit.DataType.AbsoluteUri); //Uri.EscapeUriString(lit.DataType.ToString())); context.Writer.WriteString(lit.Value); } } else if (!lit.Language.Equals(String.Empty)) { // Language specified Literal context.Writer.WriteAttributeString("xml", "lang", null, lit.Language); context.Writer.WriteString(lit.Value); } else { // Simple Literal context.Writer.WriteString(lit.Value); } break; case NodeType.Uri: // Simple rdf:resource // TODO: Compress this into UriRef where possible context.Writer.WriteAttributeString("rdf", "resource", NamespaceMapper.RDF, t.Object.ToString()); //Uri.EscapeUriString(t.Object.ToString())); break; case NodeType.Variable: throw new RdfOutputException(WriterErrorMessages.VariableNodesUnserializable("RDF/XML")); } }
/// <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(_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 = _compressionLevel; context.UseDtd = _useDTD; context.UseAttributes = _useAttributes; 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); } // Add all the existing Namespace Definitions here 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); context.Writer.WriteString(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri);//Uri.EscapeUriString(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri)); context.Writer.WriteEndAttribute(); } else { context.Writer.WriteStartAttribute("xmlns"); context.Writer.WriteString(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri);//Uri.EscapeUriString(context.NamespaceMap.GetNamespaceUri(prefix).AbsoluteUri)); context.Writer.WriteEndAttribute(); } } // Find the Collections and Type References if (context.CompressionLevel >= WriterCompressionLevel.More) { WriterHelper.FindCollections(context, CollectionSearchMode.All); } // Get the Triples as a Sorted List List <Triple> ts = context.Graph.Triples.Where(t => !context.TriplesDone.Contains(t)).ToList(); ts.Sort(new RdfXmlTripleComparer()); INode lastSubj = null; List <Triple> sameSubject = new List <Triple>(); for (int i = 0; i < ts.Count; i++) { // Find the first group of Triples with the same subject if (lastSubj == null) { // Start of new set of Triples with the same subject lastSubj = ts[i].Subject; sameSubject.Add(ts[i]); if (lastSubj.NodeType == NodeType.GraphLiteral) { throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("RDF/XML")); } else if (lastSubj.NodeType == NodeType.Variable) { throw new RdfOutputException(WriterErrorMessages.VariableNodesUnserializable("RDF/XML")); } } else { if (ts[i].Subject.Equals(lastSubj)) { // Still finding Triples with same subject sameSubject.Add(ts[i]); } else { // Found the end of current set of Triples with same subject GenerateSubjectOutput(context, sameSubject, true); // Reset so we'll start from a new subject on next iteration sameSubject.Clear(); lastSubj = null; i--; } } } // Ensure last set of Triples with same subject gets written if (sameSubject.Count > 0) { GenerateSubjectOutput(context, sameSubject, true); } // Take care of any collections that weren't yet written foreach (KeyValuePair <INode, OutputRdfCollection> kvp in context.Collections) { if (!kvp.Value.HasBeenWritten) { // Generate a rdf:Description node and then write the collection context.Writer.WriteStartElement("rdf", "Description", NamespaceMapper.RDF); if (kvp.Value.Triples.Count > 0 || !kvp.Value.IsExplicit) { context.Writer.WriteAttributeString("rdf", "nodeID", NamespaceMapper.RDF, context.BlankNodeMapper.GetOutputID(((IBlankNode)kvp.Key).InternalID)); } GenerateCollectionOutput(context, kvp.Key); context.Writer.WriteEndElement(); } } context.NamespaceMap.DecrementNesting(); context.Writer.WriteEndDocument(); // Save to the Output Stream context.Writer.Flush(); }