1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
"""
A commandline tool for drawing RDFS Class diagrams in Graphviz DOT
format
You can draw the graph of an RDFS file directly:
.. code-block: bash
rdf2dot my_rdfs_file.rdf | dot -Tpng | display
"""
import rdflib.extras.cmdlineutils
import sys
import itertools
import collections
from rdflib import XSD, RDF, RDFS
XSDTERMS = [XSD[x] for x in (
"anyURI", "base64Binary", "boolean", "byte", "date", "dateTime", "decimal",
"double", "duration", "float", "gDay", "gMonth", "gMonthDay", "gYear",
"gYearMonth", "hexBinary", "ID", "IDREF", "IDREFS", "int", "integer",
"language", "long", "Name", "NCName", "negativeInteger", "NMTOKEN",
"NMTOKENS", "nonNegativeInteger", "nonPositiveInteger", "normalizedString",
"positiveInteger", "QName", "short", "string", "time", "token",
"unsignedByte", "unsignedInt", "unsignedLong", "unsignedShort")]
EDGECOLOR = "blue"
NODECOLOR = "black"
ISACOLOR = "black"
def rdfs2dot(g, stream, opts={}):
"""
Convert the RDFS schema in a graph
writes the dot output to the stream
"""
fields = collections.defaultdict(set)
nodes = {}
def node(x):
if x not in nodes:
nodes[x] = "node%d" % len(nodes)
return nodes[x]
def label(x, g):
l = g.value(x, RDFS.label)
if l is None:
try:
l = g.namespace_manager.compute_qname(x)[2]
except:
pass # bnodes and some weird URIs cannot be split
return l
stream.write(u"digraph { \n node [ fontname=\"DejaVu Sans\" ] ; \n")
for x in g.subjects(RDF.type, RDFS.Class):
n = node(x)
for x, y in g.subject_objects(RDFS.subClassOf):
x = node(x)
y = node(y)
stream.write(u"\t%s -> %s [ color=%s ] ;\n" % (y, x, ISACOLOR))
for x in g.subjects(RDF.type, RDF.Property):
for a, b in itertools.product(
g.objects(x, RDFS.domain), g.objects(x, RDFS.range)):
if b in XSDTERMS or b == RDFS.Literal:
l = label(b, g)
if b == RDFS.Literal:
l = "literal"
fields[node(a)].add((label(x, g), l))
else:
# if a in nodes and b in nodes:
stream.write(
"\t%s -> %s [ color=%s, label=\"%s\" ];\n" % (
node(a), node(b), EDGECOLOR, label(x, g)))
for u, n in nodes.items():
stream.write(u"# %s %s\n" % (u, n))
f = [u"<tr><td align='left'>%s</td><td>%s</td></tr>" %
x for x in sorted(fields[n])]
opstr = u"%s [ shape=none, color=%s label=< <table color='#666666'" + \
u" cellborder=\"0\" cellspacing='0' border=\"1\"><tr>" + \
u"<td colspan=\"2\" bgcolor='grey'><B>%s</B></td>" + \
u"</tr>%s</table> > ] \n"
stream.write(opstr % (n, NODECOLOR, label(u, g), u"".join(f)))
stream.write("}\n")
def _help():
sys.stderr.write("""
rdfs2dot.py [-f <format>] files...
Read RDF files given on STDOUT, writes a graph of the RDFS schema in
DOT language to stdout
-f specifies parser to use, if not given,
""")
def main():
rdflib.extras.cmdlineutils.main(rdfs2dot, _help)
if __name__ == '__main__':
main()
|