69807
|
1 |
/* Title: Pure/General/rdf.scala
|
|
2 |
Author: Makarius
|
|
3 |
|
|
4 |
Support for RDF/XML representation, see also:
|
|
5 |
- https://www.w3.org/RDF
|
|
6 |
- https://www.w3.org/TR/rdf-primer
|
|
7 |
*/
|
|
8 |
|
|
9 |
package isabelle
|
|
10 |
|
|
11 |
|
69809
|
12 |
import java.net.URI
|
|
13 |
|
|
14 |
|
69807
|
15 |
object RDF
|
|
16 |
{
|
|
17 |
/* document */
|
|
18 |
|
|
19 |
val rdf: XML.Namespace = XML.Namespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
|
20 |
val dc: XML.Namespace = XML.Namespace("dc", "http://purl.org/dc/elements/1.1/")
|
|
21 |
|
|
22 |
val default_namespaces: List[XML.Namespace] = List(rdf, dc)
|
|
23 |
|
|
24 |
def document(body: XML.Body,
|
|
25 |
namespaces: List[XML.Namespace] = default_namespaces,
|
|
26 |
attributes: XML.Attributes = Nil): XML.Elem =
|
|
27 |
{
|
|
28 |
XML.Elem(Markup(rdf("RDF"), namespaces.map(_.attribute) ::: attributes), body)
|
|
29 |
}
|
|
30 |
|
|
31 |
|
|
32 |
/* multiple triples vs. compact description */
|
|
33 |
|
|
34 |
sealed case class Triple(subject: String, predicate: String, `object`: XML.Body)
|
|
35 |
{
|
|
36 |
def property: XML.Elem = XML.elem(predicate, `object`)
|
|
37 |
}
|
|
38 |
|
|
39 |
def triples(args: List[Triple]): XML.Body =
|
|
40 |
args.groupBy(_.subject).toList.map(
|
|
41 |
{ case (subject, ts) => description(subject, ts.map(_.property)) })
|
|
42 |
|
|
43 |
def description(subject: String, body: XML.Body, attributes: XML.Attributes = Nil): XML.Elem =
|
|
44 |
XML.Elem(Markup(rdf("Description"), (rdf("about"), subject) :: attributes), body)
|
69808
|
45 |
|
|
46 |
|
|
47 |
/* collections */
|
|
48 |
|
|
49 |
def collection(kind: String, items: List[XML.Body]): XML.Elem =
|
|
50 |
XML.elem(kind, items.map(item => XML.elem(rdf("li"), item)))
|
|
51 |
|
|
52 |
def bag(items: List[XML.Body]): XML.Elem = collection(rdf("Bag"), items)
|
|
53 |
def seq(items: List[XML.Body]): XML.Elem = collection(rdf("Seq"), items)
|
|
54 |
def alt(items: List[XML.Body]): XML.Elem = collection(rdf("Alt"), items)
|
69809
|
55 |
|
|
56 |
|
|
57 |
/* datatypes */
|
|
58 |
|
|
59 |
// see https://www.w3.org/TR/rdf11-concepts/#section-Datatypes
|
|
60 |
// see https://www.w3.org/TR/xmlschema-2/#built-in-datatypes
|
|
61 |
|
|
62 |
def string(x: String): XML.Body = if (x.isEmpty) Nil else List(XML.Text(x))
|
|
63 |
def uri(x: URI): XML.Body = string(x.toString)
|
|
64 |
def bool(x: Boolean): XML.Body = string(x.toString)
|
|
65 |
def int(x: Int): XML.Body = string(Value.Int(x))
|
|
66 |
def long(x: Long): XML.Body = string(Value.Long(x))
|
|
67 |
def double(x: Double): XML.Body = string(Value.Double(x))
|
|
68 |
def seconds(x: Time): XML.Body = double(x.seconds)
|
|
69 |
def date_time_stamp(x: Date): XML.Body = string(Date.Format("uuuu-MM-dd'T'HH:mm:ss.SSSxxx")(x))
|
69858
|
70 |
|
|
71 |
|
|
72 |
/* predicates */
|
|
73 |
|
|
74 |
object Property // binary relation with plain value
|
|
75 |
{
|
|
76 |
val title: String = dc("title")
|
|
77 |
val creator: String = dc("creator")
|
|
78 |
val contributor: String = dc("contributor")
|
|
79 |
val date: String = dc("date")
|
|
80 |
val description: String = dc("description")
|
|
81 |
}
|
69807
|
82 |
}
|