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 / XMLSerializer.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  3.9 KB  |  115 lines

  1. from __future__ import generators
  2.  
  3. from rdflib.syntax.serializers import Serializer
  4.  
  5. from rdflib.URIRef import URIRef
  6. from rdflib.Literal import Literal
  7. from rdflib.BNode import BNode
  8.  
  9. from rdflib.util import uniq
  10. from rdflib.exceptions import Error
  11. from rdflib.syntax.xml_names import split_uri
  12.  
  13. from xml.sax.saxutils import quoteattr, escape
  14.  
  15.  
  16. class XMLSerializer(Serializer):
  17.  
  18.     def __init__(self, store):
  19.         super(XMLSerializer, self).__init__(store)
  20.  
  21.     def __bindings(self):
  22.         store = self.store
  23.         nm = store.namespace_manager
  24.         bindings = {}
  25.         for predicate in uniq(store.predicates()):
  26.             prefix, namespace, name = nm.compute_qname(predicate)
  27.             bindings[prefix] = URIRef(namespace)
  28.         RDFNS = URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
  29.         if "rdf" in bindings:
  30.             assert bindings["rdf"]==RDFNS
  31.         else:
  32.             bindings["rdf"] = RDFNS
  33.         for prefix, namespace in bindings.iteritems():
  34.             yield prefix, namespace
  35.  
  36.  
  37.     def serialize(self, stream, base=None, encoding=None, **args):
  38.         self.base = base
  39.         self.__stream = stream
  40.         self.__serialized = {}
  41.         encoding = self.encoding
  42.         self.write = write = lambda uni: stream.write(uni.encode(encoding, 'replace'))
  43.  
  44.         # startDocument
  45.         write('<?xml version="1.0" encoding="%s"?>\n' % self.encoding)
  46.  
  47.         # startRDF
  48.         write('<rdf:RDF\n')
  49.         # TODO: assert(namespaces["http://www.w3.org/1999/02/22-rdf-syntax-ns#"]=='rdf')
  50.         bindings = list(self.__bindings())
  51.         bindings.sort()
  52.         for prefix, namespace in bindings:
  53.             if prefix:
  54.                 write('   xmlns:%s="%s"\n' % (prefix, namespace))
  55.             else:
  56.                 write('   xmlns="%s"\n' % namespace)
  57.         write('>\n')
  58.  
  59.         # write out triples by subject
  60.         for subject in self.store.subjects():
  61.             self.subject(subject, 1)
  62.  
  63.         # endRDF
  64.         write( "</rdf:RDF>\n" )
  65.  
  66.         # Set to None so that the memory can get garbage collected.
  67.         #self.__serialized = None
  68.         del self.__serialized
  69.  
  70.  
  71.     def subject(self, subject, depth=1):
  72.         if not subject in self.__serialized:
  73.             self.__serialized[subject] = 1
  74.             if isinstance(subject, (BNode,URIRef)):
  75.                 write = self.write
  76.                 indent = "  " * depth
  77.                 element_name = "rdf:Description"
  78.                 if isinstance(subject, BNode):
  79.                     write( '%s<%s rdf:nodeID="%s"' %
  80.                        (indent, element_name, subject))
  81.                 else:
  82.                     uri = quoteattr(self.relativize(subject))
  83.                     write( "%s<%s rdf:about=%s" % (indent, element_name, uri))
  84.                 if (subject, None, None) in self.store:
  85.                     write( ">\n" )
  86.                     for predicate, object in self.store.predicate_objects(subject):
  87.                         self.predicate(predicate, object, depth+1)
  88.                     write( "%s</%s>\n" % (indent, element_name))
  89.                 else:
  90.                     write( "/>\n" )
  91.  
  92.     def predicate(self, predicate, object, depth=1):
  93.         write = self.write
  94.         indent = "  " * depth
  95.         qname = self.store.namespace_manager.qname(predicate)
  96.         if isinstance(object, Literal):
  97.             attributes = ""
  98.             if object.language:
  99.                 attributes += ' xml:lang="%s"'%object.language
  100.  
  101.             if object.datatype:
  102.                 attributes += ' rdf:datatype="%s"'%object.datatype
  103.  
  104.             write("%s<%s%s>%s</%s>\n" %
  105.                   (indent, qname, attributes,
  106.                    escape(object), qname) )
  107.         else:
  108.             if isinstance(object, BNode):
  109.                 write('%s<%s rdf:nodeID="%s"/>\n' %
  110.                       (indent, qname, object))
  111.             else:
  112.                 write("%s<%s rdf:resource=%s/>\n" %
  113.                       (indent, qname, quoteattr(self.relativize(object))))
  114.  
  115.