comparison emeraldtree/tree.py @ 65:d3fcc3556413

Tree - Move remaining serialization code into writer class
author Bastian Blank <bblank@thinkmo.de>
date Sun, 30 May 2010 16:55:41 +0200
parents bd93ebba58ba
children 048d2f8de762
comparison
equal deleted inserted replaced
64:bd93ebba58ba 65:d3fcc3556413
647 647
648 Writer(encoding, namespaces).write(write, self._root) 648 Writer(encoding, namespaces).write(write, self._root)
649 649
650 # -------------------------------------------------------------------- 650 # --------------------------------------------------------------------
651 # serialization support 651 # serialization support
652
653 ##
654 # Registers a namespace prefix. The registry is global, and any
655 # existing mapping for either the given prefix or the namespace URI
656 # will be removed.
657 #
658 # @param prefix Namespace prefix.
659 # @param uri Namespace uri. Tags and attributes in this namespace
660 # will be serialized with the given prefix, if at all possible.
661 # @raise ValueError If the prefix is reserved, or is otherwise
662 # invalid.
663
664 def register_namespace(prefix, uri):
665 import re
666 if re.match("ns\d+$", prefix):
667 raise ValueError("Prefix format reserved for internal use")
668 for k, v in _namespace_map.items():
669 if k == uri or v == prefix:
670 del _namespace_map[k]
671 _namespace_map[uri] = prefix
672
673 _namespace_map = {
674 # "well-known" namespace prefixes
675 "http://www.w3.org/XML/1998/namespace": "xml",
676 "http://www.w3.org/1999/xhtml": "html",
677 "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
678 "http://schemas.xmlsoap.org/wsdl/": "wsdl",
679 # xml schema
680 "http://www.w3.org/2001/XMLSchema": "xs",
681 "http://www.w3.org/2001/XMLSchema-instance": "xsi",
682 # dublic core
683 "http://purl.org/dc/elements/1.1/": "dc",
684 }
685
686 def _raise_serialization_error(text):
687 raise TypeError(
688 "cannot serialize %r (type %s)" % (text, type(text).__name__)
689 )
690 652
691 # -------------------------------------------------------------------- 653 # --------------------------------------------------------------------
692 654
693 ## 655 ##
694 # Generates a string representation of an XML element, including all 656 # Generates a string representation of an XML element, including all
1195 1157
1196 # maps qnames to *encoded* prefix:local names 1158 # maps qnames to *encoded* prefix:local names
1197 qnames = {None: None} 1159 qnames = {None: None}
1198 1160
1199 # maps uri:s to prefixes 1161 # maps uri:s to prefixes
1200 candidate_namespaces = _namespace_map.copy() 1162 candidate_namespaces = self._namespace_map.copy()
1201 candidate_namespaces = {} 1163 candidate_namespaces = {}
1202 candidate_namespaces.update(self.namespaces) 1164 candidate_namespaces.update(self.namespaces)
1203 used_namespaces = {} 1165 used_namespaces = {}
1204 1166
1205 def add_qname(qname): 1167 def add_qname(qname):
1223 qnames[qname] = qname.name 1185 qnames[qname] = qname.name
1224 else: 1186 else:
1225 # XXX: What happens with undefined namespace? 1187 # XXX: What happens with undefined namespace?
1226 qnames[qname] = qname.name 1188 qnames[qname] = qname.name
1227 except TypeError: 1189 except TypeError:
1228 _raise_serialization_error(qname) 1190 self._raise_serialization_error(qname)
1229 1191
1230 # populate qname and namespaces table 1192 # populate qname and namespaces table
1231 if isinstance(elem, Element): 1193 if isinstance(elem, Element):
1232 for elem in elem.iter(): 1194 for elem in elem.iter():
1233 if isinstance(elem, Element): 1195 if isinstance(elem, Element):
1235 if isinstance(tag, QName): 1197 if isinstance(tag, QName):
1236 add_qname(tag) 1198 add_qname(tag)
1237 elif isinstance(tag, basestring): 1199 elif isinstance(tag, basestring):
1238 add_qname(QName(tag)) 1200 add_qname(QName(tag))
1239 elif tag is not None: 1201 elif tag is not None:
1240 _raise_serialization_error(tag) 1202 self._raise_serialization_error(tag)
1241 1203
1242 for key in elem.keys(): 1204 for key in elem.keys():
1243 if isinstance(key, QName): 1205 if isinstance(key, QName):
1244 add_qname(key) 1206 add_qname(key)
1245 elif isinstance(key, basestring): 1207 elif isinstance(key, basestring):
1246 add_qname(QName(key)) 1208 add_qname(QName(key))
1247 elif key is not None: 1209 elif key is not None:
1248 _raise_serialization_error(key) 1210 self._raise_serialization_error(key)
1249 1211
1250 return qnames, used_namespaces 1212 return qnames, used_namespaces
1213
1214 @staticmethod
1215 def _raise_serialization_error(text):
1216 raise TypeError(
1217 "cannot serialize %r (type %s)" % (text, type(text).__name__)
1218 )
1219
1220 ##
1221 # Registers a namespace prefix. The registry is global, and any
1222 # existing mapping for either the given prefix or the namespace URI
1223 # will be removed.
1224 #
1225 # @param prefix Namespace prefix.
1226 # @param uri Namespace uri. Tags and attributes in this namespace
1227 # will be serialized with the given prefix, if at all possible.
1228 # @raise ValueError If the prefix is reserved, or is otherwise
1229 # invalid.
1230
1231 @classmethod
1232 def register_namespace(cls, prefix, uri):
1233 import re
1234 if re.match("ns\d+$", prefix):
1235 raise ValueError("Prefix format reserved for internal use")
1236 for k, v in cls._namespace_map.items():
1237 if k == uri or v == prefix:
1238 del _namespace_map[k]
1239 cls._namespace_map[uri] = prefix
1240
1241 _namespace_map = {
1242 # "well-known" namespace prefixes
1243 "http://www.w3.org/XML/1998/namespace": "xml",
1244 "http://www.w3.org/1999/xhtml": "html",
1245 "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
1246 "http://schemas.xmlsoap.org/wsdl/": "wsdl",
1247 # xml schema
1248 "http://www.w3.org/2001/XMLSchema": "xs",
1249 "http://www.w3.org/2001/XMLSchema-instance": "xsi",
1250 # dublic core
1251 "http://purl.org/dc/elements/1.1/": "dc",
1252 }
1251 1253
1252 def serialize_start(self, write): 1254 def serialize_start(self, write):
1253 pass 1255 pass
1254 1256
1255 def write(self, write, element): 1257 def write(self, write, element):