faster CharacterDataHandler in NodeBuilder

This commit is contained in:
Dimitur Kirov 2006-02-18 02:08:49 +00:00
parent eacf5fb900
commit 32bfde61e2
1 changed files with 354 additions and 336 deletions

View File

@ -57,8 +57,10 @@ class Node:
"node" and other arguments is provided then the node initially created as replica of "node" "node" and other arguments is provided then the node initially created as replica of "node"
provided and then modified to be compliant with other arguments.""" provided and then modified to be compliant with other arguments."""
if node: if node:
if self.FORCE_NODE_RECREATION and type(node)==type(self): node=str(node) if self.FORCE_NODE_RECREATION and type(node)==type(self):
if type(node)<>type(self): node=NodeBuilder(node,self) node=str(node)
if type(node)<>type(self):
node=NodeBuilder(node,self)
else: else:
self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = node.name,node.namespace,{},[],[],node.parent self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = node.name,node.namespace,{},[],[],node.parent
for key in node.attrs.keys(): self.attrs[key]=node.attrs[key] for key in node.attrs.keys(): self.attrs[key]=node.attrs[key]
@ -282,8 +284,8 @@ class NodeBuilder:
self._parser = xml.parsers.expat.ParserCreate(namespace_separator=' ') self._parser = xml.parsers.expat.ParserCreate(namespace_separator=' ')
self._parser.StartElementHandler = self.starttag self._parser.StartElementHandler = self.starttag
self._parser.EndElementHandler = self.endtag self._parser.EndElementHandler = self.endtag
self._parser.CharacterDataHandler = self.handle_data
self._parser.StartNamespaceDeclHandler = self.handle_namespace_start self._parser.StartNamespaceDeclHandler = self.handle_namespace_start
self._parser.CharacterDataHandler = self.handle_cdata
self.Parse = self._parser.Parse self.Parse = self._parser.Parse
self.__depth = 0 self.__depth = 0
@ -292,10 +294,13 @@ class NodeBuilder:
self._mini_dom=initial_node self._mini_dom=initial_node
self.last_is_data = 1 self.last_is_data = 1
self._ptr=None self._ptr=None
self.data_buffer = None
self.namespaces={"http://www.w3.org/XML/1998/namespace":'xml:'} self.namespaces={"http://www.w3.org/XML/1998/namespace":'xml:'}
self.xmlns="http://www.w3.org/XML/1998/namespace" self.xmlns="http://www.w3.org/XML/1998/namespace"
if data: self._parser.Parse(data,1) if data:
self._parser.Parse(data,1)
def destroy(self): def destroy(self):
""" Method used to allow class instance to be garbage-collected. """ """ Method used to allow class instance to be garbage-collected. """
@ -316,8 +321,10 @@ class NodeBuilder:
self.__depth += 1 self.__depth += 1
self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s, attrs -> %s" % (self.__depth, tag, `attrs`), 'down') self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s, attrs -> %s" % (self.__depth, tag, `attrs`), 'down')
if self.__depth == self._dispatch_depth: if self.__depth == self._dispatch_depth:
if not self._mini_dom : self._mini_dom = Node(tag=tag, attrs=attrs) if not self._mini_dom :
else: Node.__init__(self._mini_dom,tag=tag, attrs=attrs) self._mini_dom = Node(tag=tag, attrs=attrs)
else:
Node.__init__(self._mini_dom,tag=tag, attrs=attrs)
self._ptr = self._mini_dom self._ptr = self._mini_dom
elif self.__depth > self._dispatch_depth: elif self.__depth > self._dispatch_depth:
self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs)) self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs))
@ -326,12 +333,15 @@ class NodeBuilder:
self._document_attrs = attrs self._document_attrs = attrs
ns, name = (['']+tag.split())[-2:] ns, name = (['']+tag.split())[-2:]
self.stream_header_received(ns, name, attrs) self.stream_header_received(ns, name, attrs)
if not self.last_is_data and self._ptr.parent: self._ptr.parent.data.append('') if not self.last_is_data and self._ptr.parent:
self._ptr.parent.data.append('')
self.last_is_data = 0 self.last_is_data = 0
def endtag(self, tag ): def endtag(self, tag ):
"""XML Parser callback. Used internally""" """XML Parser callback. Used internally"""
self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s" % (self.__depth, tag), 'up') self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s" % (self.__depth, tag), 'up')
if self.data_buffer:
self._ptr.data.append(''.join(self.data_buffer))
self.data_buffer = None
if self.__depth == self._dispatch_depth: if self.__depth == self._dispatch_depth:
self.dispatch(self._mini_dom) self.dispatch(self._mini_dom)
elif self.__depth > self._dispatch_depth: elif self.__depth > self._dispatch_depth:
@ -342,7 +352,15 @@ class NodeBuilder:
self.last_is_data = 0 self.last_is_data = 0
if self.__depth == 0: self.stream_footer_received() if self.__depth == 0: self.stream_footer_received()
def handle_data(self, data): def handle_cdata(self, data):
if self.last_is_data:
if self.data_buffer:
self.data_buffer.append(data)
else:
self.data_buffer = [data]
self.last_is_data = 1
def handle_data(self, data, *args):
"""XML Parser callback. Used internally""" """XML Parser callback. Used internally"""
self.DEBUG(DBG_NODEBUILDER, data, 'data') self.DEBUG(DBG_NODEBUILDER, data, 'data')
if not self._ptr: return if not self._ptr: return