/// <summary> /// Serializes the given graph to the given stream using TriX data format. /// </summary> internal static void Serialize(RDFGraph graph, Stream outputStream) { try { #region serialize using (XmlTextWriter trixWriter = new XmlTextWriter(outputStream, Encoding.UTF8)) { XmlDocument trixDoc = new XmlDocument(); trixWriter.Formatting = Formatting.Indented; #region xmlDecl XmlDeclaration trixDecl = trixDoc.CreateXmlDeclaration("1.0", "UTF-8", null); trixDoc.AppendChild(trixDecl); #endregion #region trixRoot XmlNode trixRoot = trixDoc.CreateNode(XmlNodeType.Element, "TriX", null); XmlAttribute trixRootNS = trixDoc.CreateAttribute("xmlns"); XmlText trixRootNSText = trixDoc.CreateTextNode("http://www.w3.org/2004/03/trix/trix-1/"); trixRootNS.AppendChild(trixRootNSText); trixRoot.Attributes.Append(trixRootNS); #region graph XmlNode graphElement = trixDoc.CreateNode(XmlNodeType.Element, "graph", null); XmlNode graphUriElement = trixDoc.CreateNode(XmlNodeType.Element, "uri", null); XmlText graphUriElementT = trixDoc.CreateTextNode(graph.ToString()); graphUriElement.AppendChild(graphUriElementT); graphElement.AppendChild(graphUriElement); #region triple foreach (var t in graph) { XmlNode tripleElement = trixDoc.CreateNode(XmlNodeType.Element, "triple", null); #region subj XmlNode subjElement = (((RDFResource)t.Subject).IsBlank ? trixDoc.CreateNode(XmlNodeType.Element, "id", null) : trixDoc.CreateNode(XmlNodeType.Element, "uri", null)); XmlText subjElementText = trixDoc.CreateTextNode(t.Subject.ToString()); subjElement.AppendChild(subjElementText); tripleElement.AppendChild(subjElement); #endregion #region pred XmlNode uriElementP = trixDoc.CreateNode(XmlNodeType.Element, "uri", null); XmlText uriTextP = trixDoc.CreateTextNode(t.Predicate.ToString()); uriElementP.AppendChild(uriTextP); tripleElement.AppendChild(uriElementP); #endregion #region object if (t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO) { XmlNode objElement = (((RDFResource)t.Object).IsBlank ? trixDoc.CreateNode(XmlNodeType.Element, "id", null) : trixDoc.CreateNode(XmlNodeType.Element, "uri", null)); XmlText objElementText = trixDoc.CreateTextNode(t.Object.ToString()); objElement.AppendChild(objElementText); tripleElement.AppendChild(objElement); } #endregion #region literal else { #region plain literal if (t.Object is RDFPlainLiteral) { XmlNode plainLiteralElement = trixDoc.CreateNode(XmlNodeType.Element, "plainLiteral", null); if (((RDFPlainLiteral)t.Object).Language != string.Empty) { XmlAttribute xmlLang = trixDoc.CreateAttribute(string.Concat(RDFVocabulary.XML.PREFIX, ":lang"), RDFVocabulary.XML.BASE_URI); XmlText xmlLangText = trixDoc.CreateTextNode(((RDFPlainLiteral)t.Object).Language); xmlLang.AppendChild(xmlLangText); plainLiteralElement.Attributes.Append(xmlLang); } XmlText plainLiteralText = trixDoc.CreateTextNode(RDFModelUtilities.EscapeControlCharsForXML(HttpUtility.HtmlDecode(((RDFLiteral)t.Object).Value))); plainLiteralElement.AppendChild(plainLiteralText); tripleElement.AppendChild(plainLiteralElement); } #endregion #region typed literal else { XmlNode typedLiteralElement = trixDoc.CreateNode(XmlNodeType.Element, "typedLiteral", null); XmlAttribute datatype = trixDoc.CreateAttribute("datatype"); XmlText datatypeText = trixDoc.CreateTextNode(RDFModelUtilities.GetDatatypeFromEnum(((RDFTypedLiteral)t.Object).Datatype)); datatype.AppendChild(datatypeText); typedLiteralElement.Attributes.Append(datatype); XmlText typedLiteralText = trixDoc.CreateTextNode(RDFModelUtilities.EscapeControlCharsForXML(HttpUtility.HtmlDecode(((RDFLiteral)t.Object).Value))); typedLiteralElement.AppendChild(typedLiteralText); tripleElement.AppendChild(typedLiteralElement); } #endregion } #endregion graphElement.AppendChild(tripleElement); } #endregion trixRoot.AppendChild(graphElement); #endregion trixDoc.AppendChild(trixRoot); #endregion trixDoc.Save(trixWriter); } #endregion } catch (Exception ex) { throw new RDFModelException("Cannot serialize TriX because: " + ex.Message, ex); } }