Ticket #3083: ignore-fucked-up-xmlns.patch
| File ignore-fucked-up-xmlns.patch, 7.2 KB (added by dwd, 18 months ago) |
|---|
-
src/common/xmpp/simplexml.py
49 49 replication (and using replication only to move upwards on the classes tree). 50 50 """ 51 51 FORCE_NODE_RECREATION=0 52 def __init__(self, tag=None, attrs={}, payload=[], parent=None, n ode=None):52 def __init__(self, tag=None, attrs={}, payload=[], parent=None, nsp=None, node_built=False, node=None): 53 53 """ Takes "tag" argument as the name of node (prepended by namespace, if needed and separated from it 54 54 by a space), attrs dictionary as the set of arguments, payload list as the set of textual strings 55 55 and child nodes that this node carries within itself and "parent" argument that is another node … … 62 62 node=str(node) 63 63 if not isinstance(node, Node): 64 64 node=NodeBuilder(node,self) 65 node_built = True 65 66 else: 66 self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = node.name,node.namespace,{},[],[],node.parent67 self.name,self.namespace,self.attrs,self.data,self.kids,self.parent,self.nsd = node.name,node.namespace,{},[],[],node.parent,{} 67 68 for key in node.attrs.keys(): self.attrs[key]=node.attrs[key] 68 69 for data in node.data: self.data.append(data) 69 70 for kid in node.kids: self.kids.append(kid) 70 else: self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = 'tag','',{},[],[],None 71 72 if tag: self.namespace, self.name = ([self.namespace]+tag.split())[-2:] 73 if parent: self.parent = parent 74 if self.parent and not self.namespace: self.namespace=self.parent.namespace 75 for attr in attrs.keys(): 71 for k,v in node.nsd.items(): self.nsd[k] = v 72 else: self.name,self.namespace,self.attrs,self.data,self.kids,self.parent,self.nsd = 'tag','',{},[],[],None,{} 73 if parent: 74 self.parent = parent 75 self.nsp_cache = {} 76 if nsp: 77 for k,v in nsp.items(): self.nsp_cache[k] = v 78 for attr,val in attrs.items(): 79 if attr == 'xmlns': 80 self.nsd[u''] = val 81 elif attr.startswith('xmlns:'): 82 self.nsd[attr[6:]] = val 76 83 self.attrs[attr]=attrs[attr] 84 if tag: 85 if node_built: 86 pfx,self.name = (['']+tag.split(':'))[-2:] 87 self.namespace = self.lookup_nsp(pfx) 88 else: 89 if ' ' in tag: 90 self.namespace,self.name = tag.split() 91 else: 92 self.name = tag 77 93 if isinstance(payload, basestring): payload=[payload] 78 94 for i in payload: 79 95 if isinstance(i, Node): self.addChild(node=i) 80 96 else: self.data.append(ustr(i)) 97 98 def lookup_nsp(self,pfx=''): 99 ns = self.nsd.get(pfx,None) 100 if ns is None: 101 ns = self.nsp_cache.get(pfx,None) 102 if ns is None: 103 if self.parent: 104 ns = self.parent.lookup_nsp(pfx) 105 self.nsp_cache[pfx] = ns 106 else: 107 return 'http://www.gajim.org/xmlns/undeclared' 108 return ns 81 109 82 110 def __str__(self,fancy=0): 83 111 """ Method used to dump node into textual representation. … … 85 113 s = (fancy-1) * 2 * ' ' + "<" + self.name 86 114 if self.namespace: 87 115 if not self.parent or self.parent.namespace!=self.namespace: 88 s = s + ' xmlns="%s"'%self.namespace 116 if 'xmlns' not in self.attrs: 117 s = s + ' xmlns="%s"'%self.namespace 89 118 for key in self.attrs.keys(): 90 119 val = ustr(self.attrs[key]) 91 120 s = s + ' %s="%s"' % ( key, XMLescape(val) ) … … 111 140 def addChild(self, name=None, attrs={}, payload=[], namespace=None, node=None): 112 141 """ If "node" argument is provided, adds it as child node. Else creates new node from 113 142 the other arguments' values and adds it as well.""" 114 if namespace: name=namespace+' '+name115 143 if node: 116 144 newnode=node 117 145 node.parent = self 118 146 else: newnode=Node(tag=name, parent=self, attrs=attrs, payload=payload) 147 if namespace: 148 newnode.setNamespace(namespace) 119 149 self.kids.append(newnode) 120 150 return newnode 121 151 def addData(self, data): … … 294 324 "data" (if provided) feeded to parser immidiatedly after instance init. 295 325 """ 296 326 self.DEBUG(DBG_NODEBUILDER, "Preparing to handle incoming XML stream.", 'start') 297 self._parser = xml.parsers.expat.ParserCreate(namespace_separator=' ') 327 328 self._parser = xml.parsers.expat.ParserCreate() 298 329 self._parser.StartElementHandler = self.starttag 299 330 self._parser.EndElementHandler = self.endtag 300 331 self._parser.StartNamespaceDeclHandler = self.handle_namespace_start 301 332 self._parser.CharacterDataHandler = self.handle_cdata 302 333 self.Parse = self._parser.Parse 303 334 304 335 self.__depth = 0 305 336 self.__last_depth = 0 306 337 self.__max_depth = 0 307 338 self._dispatch_depth = 1 308 339 self._document_attrs = None 340 self._document_nsp = None 309 341 self._mini_dom=initial_node 310 342 self.last_is_data = 1 311 343 self._ptr=None 312 344 self.data_buffer = None 313 self.namespaces={"http://www.w3.org/XML/1998/namespace":'xml:'} 314 self.xmlns="http://www.w3.org/XML/1998/namespace" 315 316 if data: 345 if data: 317 346 self._parser.Parse(data,1) 318 347 319 348 def check_data_buffer(self): … … 333 362 def starttag(self, tag, attrs): 334 363 """XML Parser callback. Used internally""" 335 364 self.check_data_buffer() 336 attlist=attrs.keys() #337 for attr in attlist: # FIXME: Crude hack. And it also slows down the whole library considerably.338 sp=attr.rfind(" ") #339 if sp==-1: continue #340 ns=attr[:sp] #341 attrs[self.namespaces[ns]+attr[sp+1:]]=attrs[attr]342 del attrs[attr] #343 365 self._inc_depth() 344 366 self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s, attrs -> %s" % (self.__depth, tag, `attrs`), 'down') 345 367 if self.__depth == self._dispatch_depth: 346 368 if not self._mini_dom : 347 self._mini_dom = Node(tag=tag, attrs=attrs )369 self._mini_dom = Node(tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True) 348 370 else: 349 Node.__init__(self._mini_dom,tag=tag, attrs=attrs )371 Node.__init__(self._mini_dom,tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True) 350 372 self._ptr = self._mini_dom 351 373 elif self.__depth > self._dispatch_depth: 352 self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs ))374 self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs, node_built=True)) 353 375 self._ptr = self._ptr.kids[-1] 354 376 if self.__depth == 1: 355 self._document_attrs = attrs 356 ns, name = (['']+tag.split())[-2:] 377 self._document_attrs = {} 378 self._document_nsp = {} 379 nsp, name = (['']+tag.split(':'))[-2:] 380 for attr,val in attrs.items(): 381 if attr == 'xmlns': 382 self._document_nsp[u''] = val 383 elif attr.startswith('xmlns:'): 384 self._document_nsp[attr[6:]] = val 385 else: 386 self._document_attrs[attr] = val 387 ns = self._document_nsp.get(nsp, 'http://www.gajim.org/xmlns/undeclared-root') 357 388 self.stream_header_received(ns, name, attrs) 358 389 if not self.last_is_data and self._ptr.parent: 359 390 self._ptr.parent.data.append('') … … 383 414 def handle_namespace_start(self, prefix, uri): 384 415 """XML Parser callback. Used internally""" 385 416 self.check_data_buffer() 386 if prefix: self.namespaces[uri]=prefix+':'387 else: self.xmlns=uri388 417 def DEBUG(self, level, text, comment=None): 389 418 """ Gets all NodeBuilder walking events. Can be used for debugging if redefined.""" 390 419 def getDom(self): … … 425 454 tags though. F.e. "<b>some text <br>some more text</b>" will not work.""" 426 455 return NodeBuilder(xml).getDom() 427 456 428 # vim: se ts=3: 429 No newline at end of file 457 # vim: se ts=3:
