Subclassing cElementTree.XMLTreeBuilder

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mukappa

    #1

    Subclassing cElementTree.XMLTreeBuilder

    I found an earlier post about subclassing cElementTree.El ement which
    can't
    be done because it is a factory method. I am trying to subclass
    XMLTreeBuilder
    with success using the python implementation, but not with
    cElementTree.

    [1013]$ python
    Python 2.3.4 (#1, Feb 22 2005, 04:09:37)
    [GCC 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)] on linux2
    Type "help", "copyright" , "credits" or "license" for more information.
    >>import elementtree.Ele mentTree
    >>class X(elementtree.E lementTree.XMLT reeBuilder):
    .... pass
    ....
    >>import cElementTree
    >>class Y(cElementTree. XMLTreeBuilder) :
    .... pass
    ....
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: cannot create 'builtin_functi on_or_method' instances
    >>>
    Is it possible to subclass cElementTree.XM LTreeBuilder?

    Thanks,
    Mike

  • Fredrik Lundh

    #2
    Re: Subclassing cElementTree.XM LTreeBuilder

    "mukappa" wrote:
    Is it possible to subclass cElementTree.XM LTreeBuilder?
    no, it's a factory function. if you need to extend it, you'll have to wrap it. but
    I'm not sure I see the use case; what is it you're trying to do here?

    </F>



    Comment

    • mukappa

      #3
      Re: Subclassing cElementTree.XM LTreeBuilder

      On Jan 25, 4:32 am, "Fredrik Lundh" <fred...@python ware.comwrote:
      "mukappa" wrote:
      Is it possible to subclass cElementTree.XM LTreeBuilder?no , it's a factory function. if you need to extend it, you'll have to wrap it. but
      I'm not sure I see the use case; what is it you're trying to do here?
      >
      </F>
      I'm trying to parse xmpp stanzas coming in over a socket. Since
      cElementTree is
      more efficient, I would like to use it when available.

      Here is what I have now:

      import logging
      from elementtree import ElementTree

      class StanzaTreeBuild er(ElementTree. XMLTreeBuilder) :
      """Capture stanza elements (<streamchildre n) from parser events.

      Private methods are lifted from the old
      elementtree.XML TreeBuilder.Fan cyTreeBuilder
      """

      def __init__(self, html=0):
      """Initiali ze state variables."""
      ElementTree.XML TreeBuilder.__i nit__(self, html)
      self._parser.St artNamespaceDec lHandler = self._start_ns
      self._parser.En dNamespaceDeclH andler = self._end_ns
      self.namespaces = []
      self.level = 0
      self.stanza = None
      self.streamelem = None

      def _start(self, tag, attrib_in):
      elem = ElementTree.XML TreeBuilder._st art(self, tag, attrib_in)
      self.start(elem )

      def _start_list(sel f, tag, attrib_in):
      elem = ElementTree.XML TreeBuilder._st art_list(self, tag,
      attrib_in)
      self.start(elem )

      def _end(self, tag):
      elem = ElementTree.XML TreeBuilder._en d(self, tag)
      self.end(elem)

      def _start_ns(self, prefix, value):
      self.namespaces .insert(0, (prefix, value))

      def _end_ns(self, prefix):
      assert self.namespaces .pop(0)[0] == prefix, "implementa tion
      confused"

      def start(self, element):
      """Track nesting level (capture open <streamon first
      call)."""
      logging.debug(" start(%s): %s" %
      (self.level, ElementTree.tos tring(element)) )
      if self.streamelem is None:
      assert element.tag == "http://etherx.jabber.o rg/streams"
      self.streamelem = element
      self.stanza = element
      self.level += 1

      def end(self, element):
      """Capture stanza when nesting level is 1."""
      self.level -= 1
      if self.level == 1:
      self.stanza = element
      self.streamelem .clear()
      logging.debug(" end(%s): %s" %
      (self.level, ElementTree.tos tring(element)) )

      def stanzagen(socke t):
      """Yield open <stream ...on first call, then complete stanzas.

      Caller needs 'id' from the opening <stream>, then he needs stanzas,
      one per call. Works by parsing the socket one byte at a time, and
      yielding complete stanza at earliest opportunity (or None if none
      waiting), exits on EOF. Stanzas are returned as ElementTree
      Elements
      to give them a natural pythonic feel.

      see
      http://online.effbot.o rg/2004_12_01_arch ive.htm#element-generator"""
      p = StanzaTreeBuild er()
      data = None
      while 1:
      try:
      data = socket.recv(1)
      if not data:
      logging.info("E OF from peer")
      p.close()
      break
      p.feed(data)
      if p.stanza is not None:
      yield p.stanza
      p.stanza = None
      data = None
      except:
      if data is not None:
      logging.error(" error reading: %s" % (data))
      raise
      else:
      yield None

      Comment

      Working...