[Twisted-Python] Help using XmlStreamFactory & XmlStream : XPathQuery error?
Gabriel Rossetti
mailing_lists at evotex.ch
Wed Feb 20 10:34:09 EST 2008
Gabriel Rossetti wrote:
> Gabriel Rossetti wrote:
>> Ralph Meijer wrote:
>>> On Wed, 2008-02-20 at 10:36 +0100, Gabriel Rossetti wrote:
>>>
>>>> [..]
>>>>
>>>> I'm having some trouble with the XPath I think when trying to react
>>>> on xml messages. I am feeding the
>>>> twisted.words.xish.xmlstream.XmlStream the following :
>>>>
>>>> <?xml version="1.0" encoding="utf-8"?>
>>>> <test><feed name='monNom'>toto</feed></test>
>>>>
>>>> and the callback functions are :
>>>>
>>>> def onTest(self, element):
>>>> print "got test : ", element
>>>>
>>>> def onFeed(self, element):
>>>> print "got feed : ", element
>>>>
>>>> def onFeedFilteredByName(self, element):
>>>> print "got feed name : ", element
>>>>
>>>> def onWildcard(self, element):
>>>> print "got wildcard : ", element
>>>>
>>>> and the bootstrap is added like so :
>>>>
>>>> f.addBootstrap(xmlstream.STREAM_START_EVENT, connected)
>>>>
>>>> and the bootstrap callback is :
>>>>
>>>> def connected(self, xs):
>>>> print 'Connected!'
>>>> xs.addObserver("/test", self.onTest)
>>>> xs.addObserver("/test/feed", self.onFeed)
>>>> xs.addObserver("/test/feed[@name]", self.onFeedFilteredByName)
>>>> xs.addObserver("/*", self.onWildcard)
>>>>
>>>> The only one that gets called is "/*". I tested out the others
>>>> using XPathQuery manually with :
>>>>
>>>> xpath.XPathQuery("//feed[@name]").queryForNodes(root)[0]
>>>>
>>>> root being the above xml, and they work, I can even get the
>>>> attributes (which is what I really need to get) like so :
>>>>
>>>>
>>>> xpath.XPathQuery("//feed[@name]").queryForNodes(root)[0].getAttribute("name")
>>>>
>>>>
>>>> What am I doing wrong when adding observers? How can I get them to
>>>> react on attribute names too?
>>>>
>>>
>>> Hi,
>>>
>>> A somewhat lengthy explanation follows,
>>>
>>> XML Streams are a result of the work on Jabber. As such, the
>>> generalized
>>> version of XmlStream in xish works similarly, but without the Jabber
>>> specifics in terms of namespaces and elements. However, the concept
>>> behind XML Streams is that you open the stream with a root element, and
>>> after that the units of exchange are the first-level childs of that
>>> root
>>> element, or so-called XML Stanzas.
>>>
>>> EventDispatcher, a superclass of XmlStream, is responsible for calling
>>> back observers upon calls to its dispatch method. For each XML Stanza,
>>> XmlStream will dispatch the DOM object at the root of that snippet of
>>> XML (domish.Element) for the XML Stanza. Observers are registered to
>>> XPath (-like) queries to match those Elements.
>>>
>>> Now that's out of the way, in your specific example, the <feed/>
>>> element
>>> would be an XML Stanza. So you can only register an observer to that,
>>> like this:
>>>
>>> xs.addObserver('/feed', self.onFeed)
>>>
>>> If some <feed/>'s would have child <title/>, you could add an observer
>>> on just those <feed/>'s with a title like this:
>>>
>>> xs.addObserver('/feed/title', self.onFeedWithTitle)
>>>
>>> The observer would still get the whole <feed/> element passed. So,
>>> to be
>>> clear: the XPath-like queries are for matching against XML Stanzas, and
>>> each XML Stanza that matches is then passed to the callbacks registered
>>> to that query.
>>>
>>> For completeness, ff you want to hook up an event to the start tag of
>>> the root element having been received, you'd do this:
>>>
>>> xs.addObserver(STREAM_START_EVENT, self.onTest)
>>>
>>> In that case, you need to do change the bootstrap registration to this:
>>>
>>> f.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, connected)
>>>
>>> Hope that clears some things up.
>>>
>>>
>> Ralph, Thank you! Your explanation cleared up a lot for me, I had
>> misunderstood the whole thing, this is exactly what I needed.
>>
>> Thanks again,
>> Gabriel
>>
>>
>> _______________________________________________
>> Twisted-Python mailing list
>> Twisted-Python at twistedmatrix.com
>> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>>
> Hi, one more question,
>
> I'm trying to do the following :
>
> receive an xml message, run different actions depending on XML
> Stanzas, modify the original message and send it back.
I forgot to say that when I say send it back, it may be also sent to
another server instead of back to the client that originally sent it,
kind of like a forwarder that modifies some of the data before sending
it along.
> I'm starting to wonder if XmlStream is really what I need? If I'm not
> mistaking, I have no way of getting the original message as a whole,
> correct? And if I'm not mistaking, if I have multiple connections,
> then the events get mixed up (from my own tests anyways), the
> processing is not atomic. If I have let's say that I have :
>
> client1 : <test><header id="1"/>
> client2 : <test><header id="2"/><feed name="myName">toto</feed></test>
> client2 : <feed name="myName2">lala</feed></test>
>
> my stanzas will get processed in that order, thus I can't even
> recreate the message (without a complicated state machine of some kind).
>
> I'm kind of mixed up, because when using a thread based network
> framework, one tcp connection = one thread, thus the protocol
> execution is atomic, but this doesn't seam to be the case with Twisted
> (event based), is this correct or have I missed something again?
>
> Thanks,
> Gabriel
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>
More information about the Twisted-Python
mailing list