class rdfDict: """ Provides a dictionary-like wrapper around a set of RDF triples with a common subject. In addition to the standard dictionary interface provides convenience methods for manipulating the triples. """ def __init__(self, subject, rdfStore=None): """ Creates a new rdfDict given the particular subject and an optional TripleStore (rdfStore). If no TripleStore is provided, creates a new one. """ # store the subject self.subject = subject # store or create the triple store if rdfStore is None: self.store = TripleStore() else: self.store = rdfStore def __str__(self): """ Return the string representation of this instance using an algorithm inspired by the Dublic Core dumb-down method. """ output_str = '' pairs = [] type_item = None for key in self: if (key.find("#type") != -1): type_item = key else: pairs.append((key, self.getAll(key))) output_str = str(self.getFirst(type_item)) + ": " for pair in pairs: output_str = '%s %s: %s;' % (output_str, str(pair[0]), ", ".join([str(n) for n in pair[1]]) ) return output_str def about(self): """ Return the subject used to create the instance (usually equivalent to rdf:about. """ return self.subject def __getvalues(self, key): """ Returns a list of values for a particular key; coerces BNodes to rdfDicts and mangles Literals with language attributes (if available). """ values = [ n for n in self.store.objects(subject=self.subject, predicate=key) ] result = [] for value in values: if (isinstance(value, BNode)): # coerce to rdfDict result.append(rdfDict(value, self.store)) else: result.append(value) return result def __getitem__(self, key): """ Return the object described in RDF with a subject of self.subject and a predicate of key. If more than one match is found, raises an AmbiguousKeyError. """ result = self.__getvalues(key) if (len(result) == 0): # no item was found, throw an exception raise KeyError() elif (len(result) > 1): # check if there is more than one option raise AmbiguousKeyError() else: # otherwise return object value return result[0] def getFirst(self, key): """ Returns the first object having the predicate key. If no match is found returns None. """ if ( (self.subject, URIRef(key), None) in self.store): return self.__getvalues(key)[0] else: return None def getAll(self, key): """ Returns a list of objects which have a predicate of key. The list may be empty or contain only a single element. """ return self.__getvalues(key) def __setitem__(self, key, value): """ Adds an RDF triple of the values (self.subject, key, value); any objects with the same subject/predicate are replaced. """ if (self.subject, key, none) in self.store: del self[key] self.store.add( (self.subject, key, value) ) def add (self, key, value): """ Adds an RDF triple consisting of the subject, key and value. """ self.store.add( (self.subject, key, value) ) def addAll (self, key, values): """ Adds the list of objects in values with the same subject and predicate. """ for value in values: self.add (key, value) def __len__(self): """ Returns the number of predicate-object pairs associated with the subject self.subject. """ return len(self.store) def __delitem__(self, key): """ Removes all items with the given key. """ if (self.subject, key, None) in self.store: self.store.remove( (self.subject, key, None) ) else: raise KeyError() def remove (self, key, value): """ Removes a specific key-value pair. """ self.store.remove( (self.subject, key, value) ) def __iter__(self): """ Returns an iterator over the unique keys (predicates) for the given subject. """ return iter(sets.Set(self.store.predicates(subject=self.subject))) iterkeys = __iter__ def __contains__(self, key): """ Returns true if the given key appears as a predicate of the subject. """ return ( (self.subject, key, None) in self.store )