Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
RdfCodec.cs
1using System;
2using System.Collections.Generic;
3using System.Security.Cryptography.X509Certificates;
4using System.Text;
5using System.Threading.Tasks;
6using System.Xml;
11
13{
18 {
22 public RdfCodec()
23 {
24 }
25
29 public string[] ContentTypes => RdfContentTypes;
30
31 private static readonly string[] RdfContentTypes = new string[]
32 {
34 };
35
39 public string[] FileExtensions => RdfFileExtensions;
40
41 private static readonly string[] RdfFileExtensions = new string[]
42 {
44 };
45
49 public const string DefaultContentType = "application/rdf+xml";
50
54 public const string DefaultExtension = "rdf";
55
62 public bool Decodes(string ContentType, out Grade Grade)
63 {
64 if (Array.IndexOf(RdfContentTypes, ContentType) >= 0)
65 {
66 Grade = Grade.Ok;
67 return true;
68 }
69 else
70 {
71 Grade = Grade.NotAtAll;
72 return false;
73 }
74 }
75
85 public Task<object> DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair<string, string>[] Fields, Uri BaseUri)
86 {
87 string s = CommonTypes.GetString(Data, Encoding ?? Encoding.UTF8);
88 RdfDocument Parsed = new RdfDocument(s, BaseUri, "n", BlankNodeIdMode.Guid);
89 return Task.FromResult<object>(Parsed);
90 }
91
99 public bool Encodes(object Object, out Grade Grade, params string[] AcceptedContentTypes)
100 {
101 if (Object is RdfDocument &&
102 InternetContent.IsAccepted(RdfContentTypes, AcceptedContentTypes))
103 {
104 Grade = Grade.Excellent;
105 return true;
106 }
107 else if (Object is ISemanticModel &&
108 InternetContent.IsAccepted(RdfContentTypes, AcceptedContentTypes))
109 {
110 Grade = Grade.Barely;
111 return true;
112 }
113 else
114 {
115 Grade = Grade.NotAtAll;
116 return false;
117 }
118 }
119
127 public Task<KeyValuePair<byte[], string>> EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
128 {
129 if (Encoding is null)
130 Encoding = Encoding.UTF8;
131
132 string Text;
133
134 if (Object is RdfDocument Doc)
135 Text = Doc.Text;
136 else if (Object is ISemanticModel Model)
137 {
138 StringBuilder sb = new StringBuilder();
139 sb.Append("<?xml version=\"1.0\" encoding=\"");
140 sb.Append(Encoding.WebName);
141 sb.AppendLine("\"?>");
142
143 XmlWriterSettings Settings = new XmlWriterSettings()
144 {
145 ConformanceLevel = ConformanceLevel.Document,
146 Encoding = Encoding,
147 Indent = false,
148 NamespaceHandling = NamespaceHandling.OmitDuplicates,
149 NewLineHandling = NewLineHandling.None,
150 NewLineOnAttributes = false,
151 OmitXmlDeclaration = true,
152 WriteEndDocumentOnClose = true
153 };
154
155 using (XmlWriter w = XmlWriter.Create(sb, Settings))
156 {
157 Dictionary<string, string> Prefixes = new Dictionary<string, string>();
158 Dictionary<string, LinkedList<ISemanticTriple>> PerSubject = new Dictionary<string, LinkedList<ISemanticTriple>>();
159 string s;
160
161 foreach (ISemanticTriple Triple in Model)
162 {
163 CheckPrefix(Triple.Subject, Prefixes);
164 CheckPrefix(Triple.Predicate, Prefixes);
165 CheckPrefix(Triple.Object, Prefixes);
166
167 s = Triple.Subject.ToString();
168
169 if (!PerSubject.TryGetValue(s, out LinkedList<ISemanticTriple> List))
170 {
171 List = new LinkedList<ISemanticTriple>();
172 PerSubject[s] = List;
173 }
174
175 List.AddLast(Triple);
176 }
177
178 w.WriteStartElement("rdf", "RDF", Rdf.Namespace);
179
180 foreach (KeyValuePair<string, string> P in Prefixes)
181 w.WriteAttributeString("xmlns", P.Key, string.Empty, P.Value);
182
183 foreach (KeyValuePair<string, LinkedList<ISemanticTriple>> Subject in PerSubject)
184 {
185 w.WriteStartElement("rdf", "Description", Rdf.Namespace);
186
187 if (Subject.Value.First.Value is BlankNode SubjectBlankNode)
188 w.WriteAttributeString("rdf", "nodeID", string.Empty, SubjectBlankNode.NodeId);
189 else
190 w.WriteAttributeString("rdf", "about", string.Empty, Subject.Key);
191
192 foreach (ISemanticTriple Triple in Subject.Value)
193 {
194 if (Triple.Predicate is UriNode Predicate)
195 {
196 string Uri = Predicate.UriString;
197 string Namespace = GetNamespace(Uri);
198
199 if (Prefixes.TryGetValue(Namespace, out string Prefix))
200 {
201 string LocalName = Uri.Substring(Namespace.Length);
202 w.WriteStartElement(Prefix, LocalName, Namespace);
203 }
204 else
205 w.WriteStartElement(Uri);
206
207 if (Triple.Object is SemanticLiteral Literal)
208 {
209 if (string.IsNullOrEmpty(Literal.StringType))
210 {
211 if (Literal is StringLiteral StringLiteral &&
212 !string.IsNullOrEmpty(StringLiteral.Language))
213 {
214 w.WriteAttributeString("xml", "lang", string.Empty, StringLiteral.Language);
215 w.WriteValue(Literal.StringValue);
216 }
217 else
218 w.WriteValue(Literal.StringValue);
219 }
220 else
221 {
222 w.WriteAttributeString("rdf", "datatype", string.Empty, Literal.StringType);
223 w.WriteValue(Literal.StringValue);
224 }
225 }
226 else if (Triple.Object is BlankNode BlankNode)
227 w.WriteAttributeString("rdf", "nodeID", string.Empty, BlankNode.NodeId);
228 else if (Triple.Object is UriNode UriNode)
229 w.WriteAttributeString("rdf", "resource", string.Empty, UriNode.UriString);
230 else
231 w.WriteValue(Triple.Object.ToString());
232
233 w.WriteEndElement();
234 }
235 else
236 throw new Exception("Unable to encode semantic model as RDF document. RDF documents require predicates to be URIs.");
237 }
238
239 w.WriteEndElement();
240 }
241
242 w.WriteEndElement();
243 w.Flush();
244
245 Text = sb.ToString();
246 }
247 }
248 else
249 throw new ArgumentException("Unable to encode object.", nameof(Object));
250
251 byte[] Bin = Encoding.GetBytes(Text);
252 string ContentType = RdfContentTypes[0] + "; charset=" + Encoding.WebName;
253
254 return Task.FromResult(new KeyValuePair<byte[], string>(Bin, ContentType));
255 }
256
257 private static void CheckPrefix(ISemanticElement Element, Dictionary<string, string> Prefixes)
258 {
259 if (Element is UriNode UriNode)
260 {
261 string Namespace = GetNamespace(UriNode.UriString);
262 if (!string.IsNullOrEmpty(Namespace) && !Prefixes.ContainsKey(Namespace))
263 {
264 string Prefix = "p" + (Prefixes.Count + 1).ToString();
265 Prefixes[Namespace] = Prefix;
266 }
267 }
268 }
269
270 private static string GetNamespace(string Uri)
271 {
272 int i = Uri.LastIndexOf('#');
273 if (i >= 0)
274 return Uri.Substring(0, i + 1);
275
276 i = Uri.LastIndexOf('/');
277 if (i >= 0)
278 return Uri.Substring(0, i + 1);
279
280 return null;
281 }
282
289 public bool TryGetContentType(string FileExtension, out string ContentType)
290 {
291 if (string.Compare(FileExtension, RdfFileExtensions[0], true) == 0)
292 {
293 ContentType = RdfContentTypes[0];
294 return true;
295 }
296 else
297 {
298 ContentType = null;
299 return false;
300 }
301 }
302
309 public bool TryGetFileExtension(string ContentType, out string FileExtension)
310 {
311 if (Array.IndexOf(RdfContentTypes, ContentType) >= 0)
312 {
313 FileExtension = RdfFileExtensions[0];
314 return true;
315 }
316 else
317 {
318 FileExtension = null;
319 return false;
320 }
321 }
322 }
323}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static string GetString(byte[] Data, Encoding DefaultEncoding)
Gets a string from its binary representation, taking any Byte Order Mark (BOM) into account.
Static class managing encoding and decoding of internet content.
static bool IsAccepted(string ContentType, params string[] AcceptedContentTypes)
Checks if a given content type is acceptable.
Represents a blank node
Definition: BlankNode.cs:7
string NodeId
Blank node Node ID.
Definition: BlankNode.cs:33
Abstract base class for semantic literal values.
RDF Schema Ontology
Definition: Rdf.cs:9
const string Namespace
http://www.w3.org/1999/02/22-rdf-syntax-ns#
Definition: Rdf.cs:13
Encoder and Decoder of semantic information in RDF Documents.
Definition: RdfCodec.cs:18
bool Encodes(object Object, out Grade Grade, params string[] AcceptedContentTypes)
If the encoder encodes a specific object.
Definition: RdfCodec.cs:99
Task< object > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object
Definition: RdfCodec.cs:85
const string DefaultExtension
rdf
Definition: RdfCodec.cs:54
bool Decodes(string ContentType, out Grade Grade)
If the decoder decodes content of a given Internet Content Type.
Definition: RdfCodec.cs:62
bool TryGetFileExtension(string ContentType, out string FileExtension)
Tries to get the file extension of content of a given content type.
Definition: RdfCodec.cs:309
RdfCodec()
Encoder and Decoder of semantic information in RDF Documents.
Definition: RdfCodec.cs:22
const string DefaultContentType
application/rdf+xml
Definition: RdfCodec.cs:49
Task< KeyValuePair< byte[], string > > EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
Encodes an object
Definition: RdfCodec.cs:127
string[] ContentTypes
Supported Internet Content Types.
Definition: RdfCodec.cs:29
string[] FileExtensions
Supported file extensions.
Definition: RdfCodec.cs:39
bool TryGetContentType(string FileExtension, out string ContentType)
Tries to get the content type of content of a given file extension.
Definition: RdfCodec.cs:289
Contains semantic information stored in an RDF document.
Definition: RdfDocument.cs:21
Basic interface for Internet Content decoders. A class implementing this interface and having a defau...
Basic interface for Internet Content encoders. A class implementing this interface and having a defau...
Interface for semantic nodes.
Interface for semantic models.
Interface for semantic triples.
ISemanticElement Object
Object element
ISemanticElement Predicate
Predicate element
ISemanticElement Subject
Subject element
BlankNodeIdMode
How blank node IDs are generated
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.
Grade
Grade enumeration
Definition: Grade.cs:7