[Twisted-Python] xmlstream problem

Ralph Meijer twisted at ralphm.ik.nu
Tue May 20 13:37:15 EDT 2008


On Tue, 2008-05-20 at 17:50 +0200, Gabriel Rossetti wrote:
> Hello,
> 
> I am using xmlstream.XmlStream to process...XML streams :-)
> I'm having a bit of a problem, I have a client and a server, both 
> protocols inherit from xmlstream.XmlStream. When the client sends 4 
> messages, one after another, I get a parse error. I debugged my program, 
> and the buffer the expat parser is given contains in effect, 4 messages 
> consecutively like so :
> 
> str: 
> <message>...</message><message>...</message><message>...</message><message>...</message>
> 
> (I replaced the child elements with "..." for your reading enjoyment)
> 
> and I get this Exception when debugging (otherwise it stays hidden) :
> 
> ExpatError: junk after document element: line 1, column 196
> 
> now column 196 is the end of the 1st msg's root element, I think it 
> doesn't like the next message being right after the first.

That's right. Streaming XML, as implemented by twisted.words.xish, works
by exchanging two complete (virtual) XML documents, one in each
direction. So, you need to have a root element around your messages,
such as 'stream'. The unit of communication is first-level elements of
that root element. So, you start out with sending the start tag of the
root element, and then sending the messages.

You would set up an observer for your messages like so:

  def onMessage(message):
      print "Got message!"

  factory = XmlStreamFactory()
  factory.addBootstrap("/message", onMessage)
  
> I did 
> override xmlstream.XmlStream.onDocumentEnd()
> because I didn't want it to close the connection in between messages, 
> but in my method I told it to initialize the stream using :
> 
> self._initializeStream()
> 
> I did this since I noticed that closing the connection forces a new 
> parser to be created when the previous statement is called. The reason I 
> don't want the connection to be closed is that I'd like a persistent 
> connection to be held.

There is no need to do this, what I showed above should meet your
requirements. Also, this method is semi-private (leading _) for a
reason.

-- 
Groetjes,

ralphm





More information about the Twisted-Python mailing list