home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / syntax / serializers / PrettyXMLSerializer.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  5.1 KB  |  135 lines

  1. from rdflib import RDF
  2.  
  3. from rdflib import URIRef, Literal, BNode
  4. from rdflib.util import first, uniq, more_than
  5.  
  6. from rdflib.syntax.serializers import Serializer
  7. from rdflib.syntax.serializers.XMLWriter import XMLWriter
  8.  
  9. XMLLANG = "http://www.w3.org/XML/1998/namespacelang"
  10.  
  11.  
  12. # TODO:
  13. def fix(val):
  14.     "strip off _: from nodeIDs... as they are not valid NCNames"
  15.     if val.startswith("_:"):
  16.         return val[2:]
  17.     else:
  18.         return val
  19.  
  20.  
  21. class PrettyXMLSerializer(Serializer):
  22.  
  23.     def __init__(self, store, max_depth=3):
  24.         super(PrettyXMLSerializer, self).__init__(store)
  25.  
  26.     def serialize(self, stream, base=None, encoding=None, **args):
  27.         self.__serialized = {}
  28.         store = self.store
  29.         self.base = base
  30.         self.max_depth = args.get("max_depth", 3)
  31.         assert self.max_depth>0, "max_depth must be greater than 0"
  32.  
  33.         self.nm = nm = store.namespace_manager
  34.         self.writer = writer = XMLWriter(stream, nm, encoding)
  35.  
  36.         namespaces = {}
  37.         possible = uniq(store.predicates()) + uniq(store.objects(None, RDF.type))
  38.         for predicate in possible:
  39.             prefix, namespace, local = nm.compute_qname(predicate)
  40.             namespaces[prefix] = namespace
  41.         namespaces["rdf"] = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  42.         writer.push(RDF.RDF)
  43.         writer.namespaces(namespaces.iteritems())
  44.  
  45.         # Write out subjects that can not be inline
  46.         for subject in store.subjects():
  47.             if (None, None, subject) in store:
  48.                 if (subject, None, subject) in store:
  49.                     self.subject(subject, 1)
  50.             else:
  51.                 self.subject(subject, 1)
  52.  
  53.         # write out anything that has not yet been reached
  54.         for subject in store.subjects():
  55.             self.subject(subject, 1)
  56.  
  57.         writer.pop(RDF.RDF)
  58.  
  59.         # Set to None so that the memory can get garbage collected.
  60.         self.__serialized = None
  61.  
  62.  
  63.     def subject(self, subject, depth=1):
  64.         store = self.store
  65.         writer = self.writer
  66.         if not subject in self.__serialized:
  67.             self.__serialized[subject] = 1
  68.             type = first(store.objects(subject, RDF.type))
  69.             try:
  70.                 self.nm.qname(type)
  71.             except:
  72.                 type = None
  73.             element = type or RDF.Description
  74.             writer.push(element)
  75.             if isinstance(subject, BNode):
  76.                 def subj_as_obj_more_than(ceil):
  77.                     return more_than(store.triples((None, None, subject)), ceil)
  78.                 if (depth == 1 and subj_as_obj_more_than(0)
  79.                         ) or subj_as_obj_more_than(1):
  80.                     writer.attribute(RDF.nodeID, fix(subject))
  81.             else:
  82.                 writer.attribute(RDF.about, self.relativize(subject))
  83.             if (subject, None, None) in store:
  84.                 for predicate, object in store.predicate_objects(subject):
  85.                     if not (predicate==RDF.type and object==type):
  86.                         self.predicate(predicate, object, depth+1)
  87.             writer.pop(element)
  88.  
  89.     def predicate(self, predicate, object, depth=1):
  90.         writer = self.writer
  91.         store = self.store
  92.         writer.push(predicate)
  93.         if isinstance(object, Literal):
  94.             attributes = ""
  95.             if object.language:
  96.                 writer.attribute(XMLLANG, object.language)
  97.             if object.datatype:
  98.                 writer.attribute(RDF.datatype, object.datatype)
  99.             writer.text(object)
  100.         elif object in self.__serialized or not (object, None, None) in store:
  101.             if isinstance(object, BNode):
  102.                 if more_than(store.triples((None, None, object)), 0):
  103.                     writer.attribute(RDF.nodeID, fix(object))
  104.             else:
  105.                 writer.attribute(RDF.resource, self.relativize(object))
  106.         else:
  107.             items = []
  108.             for item in store.items(object): # add a strict option to items?
  109.                 if isinstance(item, Literal):
  110.                     items = None # can not serialize list with literal values in them with rdf/xml
  111.                 else:
  112.                     items.append(item)
  113.  
  114.             if first(store.objects(object, RDF.first)): # may not have type RDF.List
  115.                 collection = object
  116.                 self.__serialized[object] = 1
  117.                 # TODO: warn that any assertions on object other than
  118.                 # RDF.first and RDF.rest are ignored... including RDF.List
  119.                 writer.attribute(RDF.parseType, "Collection")
  120.                 while collection:
  121.                     item = first(store.objects(collection, RDF.first))
  122.                     if item:
  123.                         self.subject(item)
  124.                     collection = first(store.objects(collection, RDF.rest))
  125.                     self.__serialized[collection] = 1
  126.             else:
  127.                 if depth<=self.max_depth:
  128.                     self.subject(object, depth+1)
  129.                 elif isinstance(object, BNode):
  130.                     writer.attribute(RDF.nodeID, fix(object))
  131.                 else:
  132.                     writer.attribute(RDF.resource, self.relativize(object))
  133.         writer.pop(predicate)
  134.  
  135.