6 |
7 | Sparts is a simple, resource-centric API for RDF graphs, built on top of
8 | rdflib_.
9 |
10 | Installation
11 | ------------
12 |
13 | Sparta requires rdflib_ 2.4+.
14 |
15 | To install::
16 |
17 | python setup.py install
18 |
19 | For installation help::
20 |
21 | python setup.py install --help
22 |
23 | In examples/::
24 |
25 | example.py: Example of use
26 | example-out.txt: ouput of example script
27 | rss.py: example RSS 1.0 feed parser
28 | rss_schema.xml: partial RDF Schema/OWL for RSS 1.0 example
29 |
30 | For more information, see sparta.py and .
31 |
32 | Getting Started
33 | ---------------
34 |
35 | The easiest way to get started is to play with it; take a look at the example
36 | files above. You can also take a look through the preliminary documentation below.
37 |
38 | Sparta is a wrapper around an rdflib_ Graph. To use it,
39 | you must first instantiate one or more Graphs, make any necessary prefix mappings,
40 | and then instantiate a ThingFactory.
41 |
42 | Prefix bindings allow URIs to be referred to with a short name.
43 | For example, if "http://www.example.com/foo#" is mapped to the prefix "foo",
44 | then the URI "http://www.example.com/foo#bar" can be referred to in Sparta
45 | with the name "foo_bar".
46 |
47 | Prefix bindings are made by calling the normal bind(prefix,
48 | URI) method on the rdflib graph. You can also bind a complete URI to a
49 | string with the addAlias(alias, URI) method on the ThingFactory
50 | (this accommodates URIs that are awkward or impossible to map using
51 | prefixes).
52 |
53 | To be instantiated, a ThingFactory requires one argument; the
54 | Graph (or store) that is to be used. Optionally, you can also give a
55 | schema_store argument, which points to a separate store that contains the
56 | schema hints used to help Sparta map RDF into Python datatypes and objects. If
57 | this is not specified, the primary store will be used.
58 |
59 | This is a common idiom for setting up Sparta::
60 |
61 | from rdflib.Graph import Graph
62 | store = Graph()
63 | store.parse([URI])
64 | store.bind([prefix], [URI])
65 | Thing = ThingFactory(store)
66 |
67 | Working with Nodes
68 | ------------------
69 |
70 | Once you've bound any prefixes you need and set up the store,
71 | you're ready to work with RDF data.
72 |
73 | An RDF node is represented as a Python object in Sparta, whose properties
74 | correspond to RDF arcs. To start working with a node, you must instantiate it
75 | with its identity; there are three ways to do this.
76 |
77 | 1. Thing("prefix_localname") - Refers to the URI indicated using the
78 | prefix mapping, as described above.
79 | 2. Thing(URIRef('http://www.example.com/foo#bar')) - Refers to the
80 | URI specified.
81 | 3. Thing(None) - creates a bNode_ (blank, or anonymous RDF node).
82 |
83 | Accessing and Manipulating Data
84 | -------------------------------
85 |
86 | A node's properties can be accessed and changed by name,
87 | using the prefix mapping as explained above. For example::
88 |
89 | print foo.rdf_type
90 |
91 | will print the 'rdf_type' property of the 'foo' node.
92 |
93 | There are two ways to access a property's values, depending on what Sparta
94 | knows about it through the schema store. If it is an
95 | owl:FunctionalProperty_, or if the subject is subclassed to restrict that
96 | property with either a owl:maxCardinality_ or a owl:cardinality_ of "1", the
97 | property can be accessed as a normal, singular value; that is, it can be
98 | accessed as explained above, assigned with the '=' operator, deleted with
99 | 'del', and so forth.
100 |
101 | Otherwise, the property's value is assumed to have a cardinality greater
102 | than one, and implements a subset of the Python set() interface. For
103 | example, you can add to the set with the add method, like this::
104 |
105 | foo.children.add("bob")
106 |
107 | test for membership with the in operator, and so forth. See the PropertySet
108 | class for the exact methods implemented.
109 |
110 | Datatyping
111 | ----------
112 |
113 | An RDF predicate with one of the following as its
114 | rdfs:range_ (according to the schema store) will be mapped to these
115 | Python datatypes:
116 |
117 | * rdf:List - list
118 | * rdf:Seq - list
119 | * xs:string, xs:normalizedString, xs:token, xs:language - unicode
120 | * xs:boolean - bool
121 | * xs:decimal, xs:float, xs:double - float
122 | * xs:integer, xs:long, xs:unsignedLong, xs:unsignedInt - long
123 | * xs:nonPositiveInteger, xs:nonNegativeInteger, xs:positiveInteger,
124 | xs:negativeInteger, xs:int, xs:short, xs:byte, xs:unsignedShort,
125 | xs:unsignedByte - int
126 | * xs:anyURI - str
127 | * xs:base64Binary - (decoded base64)
128 |
129 |
130 | .. _rdflib: http://rdflib.net/
131 | .. _bnode: http://www.w3.org/TR/rdf-primer/#structuredproperties
132 | .. _cardinality: http://www.w3.org/TR/owl-ref/#cardinality
133 | .. _maxCardinality: http://www.w3.org/TR/owl-ref/#maxCardinality-def
134 | .. _FunctionalProperty: http://www.w3.org/TR/owl-ref/#FunctionalProperty-def
135 | .. _range: http://www.w3.org/TR/rdf-schema/#ch_range
--------------------------------------------------------------------------------
/sparta.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """
4 | sparta.py - a Simple API for RDF
5 |
6 | Sparta is a simple API for RDF that binds RDF nodes to Python
7 | objects and RDF arcs to attributes of those Python objects. As
8 | such, it can be considered a "data binding" from RDF to Python.
9 |
10 | Requires rdflib version 2.3.1+.
11 | """
12 |
13 | __license__ = """
14 | Copyright (c) 2001-2006 Mark Nottingham
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 | """
34 |
35 | __version__ = "0.9-pre"
36 |
37 | import base64
38 | import rdflib # http://rdflib.net/
39 | from rdflib.Identifier import Identifier as ID
40 | from rdflib.URIRef import URIRef as URI
41 | from rdflib.BNode import BNode
42 | from rdflib.Literal import Literal
43 | from rdflib import RDF, RDFS
44 |
45 | RDF_SEQi = "http://www.w3.org/1999/02/22-rdf-syntax-ns#_%s"
46 | MAX_CARD = URI("http://www.w3.org/2002/07/owl#maxCardinality")
47 | CARD = URI("http://www.w3.org/2002/07/owl#cardinality")
48 | RESTRICTION = URI("http://www.w3.org/2002/07/owl#Restriction")
49 | FUNC_PROP = URI("http://www.w3.org/2002/07/owl#FunctionalProperty")
50 | ON_PROP = URI("http://www.w3.org/2002/07/owl#onProperty")
51 | ONE = Literal("1")
52 |
53 |
54 |
55 | class ThingFactory:
56 | """
57 | Fed a store, return a factory that can be used to instantiate
58 | Things into that world.
59 | """
60 | def __init__(self, store, schema_store=None, alias_map=None):
61 | """
62 | store - rdflib.Graph.Graph instance
63 | schema_store - rdflib.Graph.Graph instance; defaults to store
64 | """
65 | self.store = store
66 | self.schema_store = schema_store or self.store
67 | self.alias_map = alias_map or {}
68 |
69 | def __call__(self, ident, **props):
70 | """
71 | ident - either:
72 | a) None (creates a new BNode)
73 | b) rdflib.URIRef.URIRef instance
74 | c) str in the form prefix_localname
75 | props - dict of properties and values, to be added. If the value is a list, its
76 | contents will be added to a ResourceSet.
77 |
78 | returns Thing instance
79 | """
80 | return Thing(self.store, self.schema_store, self.alias_map, ident, props)
81 |
82 | def addAlias(self, alias, uri):
83 | """
84 | Add an alias for an pythonic name to a URI, which overrides the
85 | default prefix_localname syntax for properties and object names. Intended to
86 | be used for URIs which are unmappable.
87 |
88 | E.g.,
89 | .addAlias("foobar", "http://example.com/my-unmappable-types#blah-type")
90 | will map the .foobar property to the provided URI.
91 | """
92 | self.alias_map[alias] = uri
93 |
94 | class Thing:
95 | """ An RDF resource, as uniquely identified by a URI. Properties
96 | of the resource are avaiable as attributes; for example:
97 | .prefix_localname is the property in the namespace mapped
98 | to the "prefix" prefix, with the localname "localname".
99 |
100 | A "python literal datatype" is a datatype that maps to a Literal type;
101 | e.g., int, float, bool.
102 |
103 | A "python data representation" is one of:
104 | a) a python literal datatype
105 | b) a self.__class__ instance
106 | c) a list containing a and/or b
107 | """
108 |
109 | def __init__(self, store, schema_store, alias_map, ident, props=None):
110 | """
111 | store - rdflib.Graph.Graph
112 | schema_store - rdflib.Graph.Graph
113 | ident - either:
114 | a) None (creates a new BNode)
115 | b) rdflib.URIRef.URIRef instance
116 | c) str in the form prefix_localname
117 | props - dict of properties and values, to be added. If the value is a list, its
118 | contents will be added to a ResourceSet.
119 | """
120 | self._store = store
121 | self._schema_store = schema_store
122 | self._alias_map = alias_map
123 | if ident is None:
124 | self._id = BNode()
125 | elif isinstance(ident, ID):
126 | self._id = ident
127 | else:
128 | self._id = self._AttrToURI(ident)
129 | if props is not None:
130 | for attr, obj in props.items():
131 | if type(obj) is type([]):
132 | [self.__getattr__(attr).add(o) for o in obj]
133 | else:
134 | self.__setattr__(attr, obj)
135 |
136 | def __getattr__(self, attr):
137 | """
138 | attr - either:
139 | a) str starting with _ (normal attribute access)
140 | b) str that is a URI
141 | c) str in the form prefix_localname
142 |
143 | returns a python data representation or a ResourceSet instance
144 | """
145 | if attr[0] == '_':
146 | raise AttributeError
147 | else:
148 | if ":" in attr:
149 | pred = URI(attr)
150 | else:
151 | try:
152 | pred = self._AttrToURI(attr)
153 | except ValueError:
154 | raise AttributeError
155 | if self._isUniqueObject(pred):
156 | try:
157 | obj = self._store.triples((self._id, pred, None)).next()[2]
158 | except StopIteration:
159 | raise AttributeError
160 | return self._rdfToPython(pred, obj)
161 | else:
162 | return ResourceSet(self, pred)
163 |
164 | def __setattr__(self, attr, obj):
165 | """
166 | attr - either:
167 | a) str starting with _ (normal attribute setting)
168 | b) str that is a URI
169 | c) str in the form prefix_localname
170 | obj - a python data representation or a ResourceSet instance
171 | """
172 | if attr[0] == '_':
173 | self.__dict__[attr] = obj
174 | else:
175 | if ":" in attr:
176 | pred = URI(attr)
177 | else:
178 | try:
179 | pred = self._AttrToURI(attr)
180 | except ValueError:
181 | raise AttributeError
182 | if self._isUniqueObject(pred):
183 | self._store.remove((self._id, pred, None))
184 | self._store.add((self._id, pred, self._pythonToRdf(pred, obj)))
185 | elif isinstance(obj, ResourceSet) or type(obj) is type(set()):
186 | ResourceSet(self, pred, obj.copy())
187 | else:
188 | raise TypeError
189 |
190 | def __delattr__(self, attr):
191 | """
192 | attr - either:
193 | a) str starting with _ (normal attribute deletion)
194 | b) str that is a URI
195 | c) str in the form prefix_localname
196 | """
197 | if attr[0] == '_':
198 | del self.__dict__[attr]
199 | else:
200 | if ":" in attr:
201 | self._store.remove((self._id, URI(attr), None))
202 | else:
203 | try:
204 | self._store.remove((self._id, self._AttrToURI(attr), None))
205 | except ValueError:
206 | raise AttributeError
207 |
208 | def _rdfToPython(self, pred, obj):
209 | """
210 | Given a RDF predicate and object, return the equivalent Python object.
211 |
212 | pred - rdflib.URIRef.URIRef instance
213 | obj - rdflib.Identifier.Identifier instance
214 |
215 | returns a python data representation
216 | """
217 | obj_types = self._getObjectTypes(pred, obj)
218 | if isinstance(obj, Literal): # typed literals
219 | return self._literalToPython(obj, obj_types)
220 | elif RDF.List in obj_types:
221 | return self._listToPython(obj)
222 | elif RDF.Seq in obj_types:
223 | l, i = [], 1
224 | while True:
225 | counter = URI(RDF_SEQi % i)
226 | try:
227 | item = self._store.triples((obj, counter, None)).next()[2]
228 | except StopIteration:
229 | return l
230 | l.append(self._rdfToPython(counter, item))
231 | i += 1
232 | elif isinstance(obj, ID):
233 | return self.__class__(self._store, self._schema_store, self._alias_map, obj)
234 | else:
235 | raise ValueError
236 |
237 | def _pythonToRdf(self, pred, obj):
238 | """
239 | Given a Python predicate and object, return the equivalent RDF object.
240 |
241 | pred - rdflib.URIRef.URIRef instance
242 | obj - a python data representation
243 |
244 | returns rdflib.Identifier.Identifier instance
245 | """
246 | obj_types = self._getObjectTypes(pred, obj)
247 | if RDF.List in obj_types:
248 | blank = BNode()
249 | self._pythonToList(blank, obj) ### this actually stores things...
250 | return blank
251 | elif RDF.Seq in obj_types: ### so will this
252 | blank = BNode()
253 | i = 1
254 | for item in obj:
255 | counter = URI(RDF_SEQi % i)
256 | self._store.add((blank, counter, self._pythonToRdf(counter, item)))
257 | i += 1
258 | return blank
259 | elif isinstance(obj, self.__class__):
260 | if obj._store is not self._store:
261 | obj.copyTo(self._store) ### and this...
262 | return obj._id
263 | else:
264 | return self._pythonToLiteral(obj, obj_types)
265 |
266 | def _literalToPython(self, obj, obj_types):
267 | """
268 | obj - rdflib.Literal.Literal instance
269 | obj_types - iterator yielding rdflib.URIRef.URIRef instances
270 |
271 | returns a python literal datatype
272 | """
273 | for obj_type in obj_types:
274 | try:
275 | return SchemaToPython[str(obj_type)][0](obj)
276 | except KeyError:
277 | pass
278 | return SchemaToPythonDefault[0](obj)
279 |
280 | def _pythonToLiteral(self, obj, obj_types):
281 | """
282 | obj - a python literal datatype
283 | obj_types - iterator yielding rdflib.URIRef.URIRef instances
284 |
285 | returns rdflib.Literal.Literal instance
286 | """
287 | for obj_type in obj_types:
288 | try:
289 | return Literal(SchemaToPython[str(obj_type)][1](obj))
290 | except KeyError:
291 | pass
292 | return Literal(SchemaToPythonDefault[1](obj))
293 |
294 | def _listToPython(self, subj):
295 | """
296 | Given a RDF list, return the equivalent Python list.
297 |
298 | subj - rdflib.Identifier.Identifier instance
299 |
300 | returns list of python data representations
301 | """
302 | try:
303 | first = self._store.triples((subj, RDF.first, None)).next()[2]
304 | except StopIteration:
305 | return []
306 | try:
307 | rest = self._store.triples((subj, RDF.rest, None)).next()[2]
308 | except StopIteration:
309 | return ValueError
310 | return [self._rdfToPython(RDF.first, first)] + self._listToPython(rest) ### type first?
311 |
312 | def _pythonToList(self, subj, members):
313 | """
314 | Given a Python list, store the eqivalent RDF list.
315 |
316 | subj - rdflib.Identifier.Identifier instance
317 | members - list of python data representations
318 | """
319 | first = self._pythonToRdf(RDF.first, members[0])
320 | self._store.add((subj, RDF.first, first))
321 | if len(members) > 1:
322 | blank = BNode()
323 | self._store.add((subj, RDF.rest, blank))
324 | self._pythonToList(blank, members[1:])
325 | else:
326 | self._store.add((subj, RDF.rest, RDF.nil))
327 |
328 | def _AttrToURI(self, attr):
329 | """
330 | Given an attribute, return a URIRef.
331 |
332 | attr - str in the form prefix_localname
333 |
334 | returns rdflib.URIRef.URIRef instance
335 | """
336 | if self._alias_map.has_key(attr):
337 | return URI(self._alias_map[attr])
338 | else:
339 | prefix, localname = attr.split("_", 1)
340 | return URI("".join([self._store.namespace_manager.store.namespace(prefix), localname]))
341 |
342 | def _URIToAttr(self, uri):
343 | """
344 | Given a URI, return an attribute.
345 |
346 | uri - str that is a URI
347 |
348 | returns str in the form prefix_localname. Not the most efficient thing around.
349 | """
350 | for alias, alias_uri in self._alias_map.items():
351 | if uri == alias_uri:
352 | return alias
353 | for ns_prefix, ns_uri in self._store.namespace_manager.namespaces():
354 | if ns_uri == uri[:len(ns_uri)]:
355 | return "_".join([ns_prefix, uri[len(ns_uri):]])
356 | raise ValueError
357 |
358 | def _getObjectTypes(self, pred, obj):
359 | """
360 | Given a predicate and an object, return a list of the object's types.
361 |
362 | pred - rdflib.URIRef.URIRef instance
363 | obj - rdflib.Identifier.Identifier instance
364 |
365 | returns list containing rdflib.Identifier.Identifier instances
366 | """
367 | obj_types = [o for (s, p, o) in self._schema_store.triples(
368 | (pred, RDFS.range, None))]
369 | if isinstance(obj, URI):
370 | obj_types += [o for (s, p, o) in self._store.triples((obj, RDF.type, None))]
371 | return obj_types
372 |
373 | def _isUniqueObject(self, pred):
374 | """
375 | Given a predicate, figure out if the object has a cardinality greater than one.
376 |
377 | pred - rdflib.URIRef.URIRef instance
378 |
379 | returns bool
380 | """
381 | # pred rdf:type owl:FunctionalProperty - True
382 | if (pred, RDF.type, FUNC_PROP) in self._schema_store:
383 | return True
384 | # subj rdf:type [ rdfs:subClassOf [ a owl:Restriction; owl:onProperty pred; owl:maxCardinality "1" ]] - True
385 | # subj rdf:type [ rdfs:subClassOf [ a owl:Restriction; owl:onProperty pred; owl:cardinality "1" ]] - True
386 | subj_types = [o for (s, p, o) in self._store.triples((self._id, RDF.type, None))]
387 | for type in subj_types:
388 | superclasses = [o for (s, p, o) in \
389 | self._schema_store.triples((type, RDFS.subClassOf, None))]
390 | for superclass in superclasses:
391 | if (
392 | (superclass, RDF.type, RESTRICTION) in self._schema_store and
393 | (superclass, ON_PROP, pred) in self._schema_store
394 | ) and \
395 | (
396 | (superclass, MAX_CARD, ONE) in self._schema_store or
397 | (superclass, CARD, ONE) in self._schema_store
398 | ): return True
399 | return False
400 |
401 | def __repr__(self):
402 | return self._id
403 |
404 | def __str__(self):
405 | try:
406 | return self._URIToAttr(self._id)
407 | except ValueError:
408 | return str(self._id)
409 |
410 | def __eq__(self, other):
411 | if isinstance(other, self.__class__):
412 | return self._id == other._id
413 | elif isinstance(other, ID):
414 | return self._id == other
415 |
416 | def __ne__(self, other):
417 | if self is other: return False
418 | else: return True
419 |
420 | def properties(self):
421 | """
422 | List unique properties.
423 |
424 | returns list containing self.__class__ instances
425 | """
426 | return [self.__class__(self._store, self._schema_store, self._alias_map, p)
427 | for (s,p,o) in self._store.triples((self._id, None, None))]
428 |
429 | def copyTo(self, store):
430 | """
431 | Recursively copy statements to the given store.
432 |
433 | store - rdflib.Store.Store
434 | """
435 | for (s, p, o) in self._store.triples((self._id, None, None)):
436 | store.add((s, p, o))
437 | if isinstance(o, (URI, BNode)):
438 | self.__class__(self._store, self._schema_store, self._alias_map, o).copyTo(store)
439 |
440 |
441 | class ResourceSet:
442 | """
443 | A set interface to the object(s) of a non-unique RDF predicate. Interface is a subset
444 | (har, har) of set().copy() returns a set.
445 | """
446 | def __init__(self, subject, predicate, iterable=None):
447 | """
448 | subject - rdflib.Identifier.Identifier instance
449 | predicate - rdflib.URIRef.URIRef instance
450 | iterable -
451 | """
452 | self._subject = subject
453 | self._predicate = predicate
454 | self._store = subject._store
455 | if iterable is not None:
456 | for obj in iterable:
457 | self.add(obj)
458 | def __len__(self):
459 | return len(list(
460 | self._store.triples((self._subject._id, self._predicate, None))))
461 | def __contains__(self, obj):
462 | if isinstance(obj, self._subject.__class__):
463 | obj = obj._id
464 | else: ### doesn't use pythonToRdf because that might store it
465 | obj_types = self._subject._getObjectTypes(self._predicate, obj)
466 | obj = self._subject._pythonToLiteral(obj, obj_types)
467 | return (self._subject._id, self._predicate, obj) in self._store
468 | def __iter__(self):
469 | for (s, p, o) in \
470 | self._store.triples((self._subject._id, self._predicate, None)):
471 | yield self._subject._pythonToRdf(self._predicate, o)
472 | def copy(self):
473 | return set(self)
474 | def add(self, obj):
475 | self._store.add((self._subject._id, self._predicate,
476 | self._subject._pythonToRdf(self._predicate, obj)))
477 | def remove(self, obj):
478 | if not obj in self:
479 | raise KeyError
480 | self.discard(obj)
481 | def discard(self, obj):
482 | if isinstance(obj, self._subject.__class__):
483 | obj = obj._id
484 | else: ### doesn't use pythonToRdf because that might store it
485 | obj_types = self._subject._getObjectTypes(self._predicate, obj)
486 | obj = self._subject._pythonToLiteral(obj, obj_types)
487 | self._store.remove((self._subject._id, self._predicate, obj))
488 | def clear(self):
489 | self._store.remove((self._subject, self._predicate, None))
490 |
491 |
492 | SchemaToPythonDefault = (unicode, unicode)
493 | SchemaToPython = { # (schema->python, python->schema) Does not validate.
494 | 'http://www.w3.org/2001/XMLSchema#string': (unicode, unicode),
495 | 'http://www.w3.org/2001/XMLSchema#normalizedString': (unicode, unicode),
496 | 'http://www.w3.org/2001/XMLSchema#token': (unicode, unicode),
497 | 'http://www.w3.org/2001/XMLSchema#language': (unicode, unicode),
498 | 'http://www.w3.org/2001/XMLSchema#boolean': (bool, lambda i:unicode(i).lower()),
499 | 'http://www.w3.org/2001/XMLSchema#decimal': (float, unicode),
500 | 'http://www.w3.org/2001/XMLSchema#integer': (long, unicode),
501 | 'http://www.w3.org/2001/XMLSchema#nonPositiveInteger': (int, unicode),
502 | 'http://www.w3.org/2001/XMLSchema#long': (long, unicode),
503 | 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger': (int, unicode),
504 | 'http://www.w3.org/2001/XMLSchema#negativeInteger': (int, unicode),
505 | 'http://www.w3.org/2001/XMLSchema#int': (int, unicode),
506 | 'http://www.w3.org/2001/XMLSchema#unsignedLong': (long, unicode),
507 | 'http://www.w3.org/2001/XMLSchema#positiveInteger': (int, unicode),
508 | 'http://www.w3.org/2001/XMLSchema#short': (int, unicode),
509 | 'http://www.w3.org/2001/XMLSchema#unsignedInt': (long, unicode),
510 | 'http://www.w3.org/2001/XMLSchema#byte': (int, unicode),
511 | 'http://www.w3.org/2001/XMLSchema#unsignedShort': (int, unicode),
512 | 'http://www.w3.org/2001/XMLSchema#unsignedByte': (int, unicode),
513 | 'http://www.w3.org/2001/XMLSchema#float': (float, unicode),
514 | 'http://www.w3.org/2001/XMLSchema#double': (float, unicode), # doesn't do the whole range
515 | # duration
516 | # dateTime
517 | # time
518 | # date
519 | # gYearMonth
520 | # gYear
521 | # gMonthDay
522 | # gDay
523 | # gMonth
524 | # hexBinary
525 | 'http://www.w3.org/2001/XMLSchema#base64Binary': (base64.decodestring, lambda i:base64.encodestring(i)[:-1]),
526 | 'http://www.w3.org/2001/XMLSchema#anyURI': (str, str),
527 | }
528 |
529 |
530 | if __name__ == '__main__':
531 | # use: "python -i sparta.py [URI for RDF file]+"
532 | from rdflib.TripleStore import TripleStore
533 | import sys
534 | mystore = TripleStore()
535 | for arg in sys.argv[1:]:
536 | mystore.parse(arg)
537 | thing = ThingFactory(mystore)
538 |
--------------------------------------------------------------------------------