Package RDFClosure :: Package serializers :: Module TurtleSerializer
[hide private]
[frames] | no frames]

Source Code for Module RDFClosure.serializers.TurtleSerializer

  1  """ 
  2   
  3  Serializer for Turtle. This is a slightly modified version of RDFLib's TurtleSerializer module; the 
  4  original version had some bugs (in defining prefixes), and the overall output look has also been slightly improved. 
  5   
  6  """ 
  7   
  8  import urlparse 
  9  from xml.sax.saxutils                   import escape, quoteattr 
 10   
 11  from rdflib.BNode                               import BNode 
 12  from rdflib.Literal                     import Literal 
 13  from rdflib.URIRef                              import URIRef 
 14  from rdflib.syntax.xml_names    import split_uri 
 15   
 16  from rdflib.syntax.serializers.RecursiveSerializer import RecursiveSerializer 
 17  from rdflib.exceptions import Error 
 18   
 19  from rdflib import RDF, RDFS 
 20   
 21  XSD = "http://www.w3.org/2001/XMLSchema#" 
 22   
 23  SUBJECT = 0 
 24  VERB = 1 
 25  OBJECT = 2 
 26   
27 -def _Literal_n3(lit,store):
28 language = lit.language 29 datatype = lit.datatype 30 # Modifying the datatype to use a prefixed value rather than the whole URI 31 # One has to be a bit careful, because user defined datatypes are also possible 32 # The rest is a copy of the original method took over from Literal 33 if datatype : 34 datatype = store.namespace_manager.normalizeUri(datatype) 35 36 # TODO: We could also chose quotes based on the quotes appearing in the string, i.e. '"' and "'" ... 37 38 # which is nicer? 39 # if lit.find("\"")!=-1 or lit.find("'")!=-1 or lit.find("\n")!=-1: 40 if lit.find("\n") != -1: 41 # Triple quote this string. 42 encoded = lit.replace('\\', '\\\\') 43 if lit.find('"""')!=-1: 44 # is this ok? 45 encoded=encoded.replace('"""','\\"""') 46 if encoded.endswith('"'): encoded=encoded[:-1]+"\\\"" 47 encoded = '"""%s"""' % encoded 48 else: 49 encoded = '"%s"' % lit.replace('\n','\\n').replace('\\', '\\\\').replace('"','\\"') 50 if language: 51 if datatype: 52 return '%s@%s^^%s' % (encoded, language, datatype) 53 else: 54 return '%s@%s' % (encoded, language) 55 else: 56 if datatype: 57 return '%s^^%s' % (encoded, datatype) 58 else: 59 return '%s' % encoded
60 61
62 -class TurtleSerializer(RecursiveSerializer):
63 short_name="turtle" 64 indentString = " "
65 - def __init__(self, store):
66 super(TurtleSerializer, self).__init__(store) 67 self.reset() 68 self.stream = None 69 self.store.namespace_manager.bind("xsd","http://www.w3.org/2001/XMLSchema#")
70
71 - def reset(self):
72 super(TurtleSerializer, self).reset() 73 self._shortNames = {} 74 self._started = False
75
76 - def getQName(self, uri):
77 if isinstance(uri, URIRef): 78 return self.store.namespace_manager.normalizeUri(uri) 79 else : 80 return None
81
82 - def preprocessTriple(self, triple):
83 super(TurtleSerializer, self).preprocessTriple(triple) 84 p = triple[1] 85 if isinstance(p, BNode): 86 self._references[p] = self.refCount(p) +1
87
88 - def label(self, node):
89 qname = self.getQName(node) 90 if qname is None: 91 if isinstance(node,Literal) : 92 return _Literal_n3(node,self.store) 93 else : 94 return node.n3() 95 return qname
96
97 - def startDocument(self):
98 self._started = True 99 ns_list= list(self.store.namespaces()) 100 ns_list.sort() 101 if len(ns_list) == 0: 102 return 103 104 for prefix, uri in ns_list: 105 self.write(self.indent() + '@prefix %s: <%s> .\n' % (prefix, uri)) 106 107 self.write('\n')
108
109 - def endDocument(self):
110 pass
111
112 - def isValidList(self,l):
113 """Checks if l is a valid RDF list.""" 114 return len([ i for i in self.store.items(l) ]) > 0
115
116 - def doList(self,l):
117 while l: 118 item = self.store.value(l, RDF.first) 119 if item: 120 self.path(item, SUBJECT) 121 self.write(' ') 122 self.subjectDone(l) 123 l = self.store.value(l, RDF.rest)
124
125 - def p_squared(self, node, position):
126 if not isinstance(node, BNode) or node in self._serialized or self.refCount(node) > 1 or position == SUBJECT: 127 return False 128 129 if self.isValidList(node): 130 # this is a list 131 self.write(' ( ') 132 self.depth += 2 133 self.doList(node) 134 self.write(')') 135 self.depth -= 2 136 else : 137 self.subjectDone(node) 138 self.depth += 2 139 self.write('\n' + self.indent() + ' [') 140 self.predicateList(node) 141 self.write('\n' + self.indent() + ' ]') 142 self.depth -= 2 143 return True
144
145 - def p_default(self, node, ignore):
146 if ignore == SUBJECT : 147 self.write(self.label(node)) 148 else : 149 self.write(" " + self.label(node)) 150 return True
151
152 - def path(self, node, position):
153 if not (self.p_squared(node, position) or self.p_default(node, position)): 154 raise Error("Cannot serialize node '%s'" % (node, ))
155
156 - def verb(self, node):
157 if node == RDF.type: 158 self.write(' a') 159 else: 160 self.path(node, VERB)
161
162 - def objectList(self, predicate, objects):
163 num = len(objects) 164 if num == 0: 165 return 166 elif num > 3 : 167 self.write('\n' + self.indent(2)) 168 169 self.path(objects[0], OBJECT) 170 for obj in objects[1:]: 171 if num > 3 : 172 self.write(',\n' + self.indent(2)) 173 else : 174 self.write(",") 175 self.path(obj, OBJECT)
176
177 - def predicateList(self, subject):
178 properties = self.buildPredicateHash(subject) 179 propList = self.sortProperties(properties) 180 if len(propList) == 0: 181 return 182 183 self.verb(propList[0]) 184 self.objectList(propList[0],properties[propList[0]]) 185 for predicate in propList[1:]: 186 self.write(' ;\n'+self.indent(1)) 187 self.verb(predicate) 188 self.objectList(predicate,properties[predicate])
189
190 - def s_squared(self, subject):
191 if (self.refCount(subject) > 0) or not isinstance(subject, BNode) : 192 return False 193 self.write('\n' + self.indent() + " [") 194 self.depth += 1 195 self.predicateList(subject) 196 self.depth -= 1 197 self.write('].') 198 return True
199
200 - def s_default(self, subject):
201 self.write('\n' + self.indent()) 202 self.path(subject, SUBJECT) 203 self.predicateList(subject) 204 self.write(' . ') 205 return True
206
207 - def statement(self, subject):
208 self.subjectDone(subject) 209 if not self.s_squared(subject): 210 self.s_default(subject)
211
212 - def serialize(self, stream, base=None, encoding=None, **args):
213 self.reset() 214 self.stream = stream 215 self.base=base 216 217 self.preprocess() 218 subjects_list = self.orderSubjects() 219 220 self.startDocument() 221 222 firstTime = True 223 for subject in subjects_list: 224 if not self.isDone(subject): 225 if firstTime: 226 firstTime = False 227 else: 228 self.write('\n') 229 self.statement(subject) 230 231 self.endDocument()
232