tags:

views:

284

answers:

2

I'm receiving data packets in XML format, each with a specific documentRoot tag, and I'd like to delegate specialized methods to take care of those packets, based on the root tag name. This worked with xml.dom.minidom, something like this:

dom = minidom.parseString(the_data)
root = dom.documentElement
deleg = getattr(self,'elem_' + str(root.tagName))
deleg(dom)

However, I want to simplify the things (in other parts of the code, not here) by using the more pythonic lxml.objectify.

The problem is I don't know how to get "root.tagName" with lxml, preferably strictly lxml.objectify. Any ideas?

A: 

FWIW in Amara Bindery you can do something like:

from amara import bindery
doc = bindery.parse(the_data)
top_elem = doc.xml_elements.next()
deleg = getattr(self, 'elem_' + str(top_elem.xml_qname))
deleg(doc)

And you get a Pythonic API as well, e.g.: doc.html.head.title = u"Change HTML document title"

Uche Ogbuji
I'm not going to edit the title of my thread in order to accept your answer, you know. But first of all, I won't switch over to something I don't want to use, just because your autobiography seems to support it :P
Flavius
Maybe I don't understand how StackOverflow works (I am new, after all), but is it improper for me to contribute another response to a thread just because an "answer" has been "accepted"? Is the point to help others who might come later? I would hope this is not all about "Flavius", because my response sure isn't.Maybe they were right on the comp.lang.python that StackOverflow is a problematic fork. I'll withhold judgment, FWIW.
Uche Ogbuji
@Uche: Fact: you answered first, then I answered, then my answer was accepted. In that context, your question is somewhat ambiguous. Can you contribute your first answer after an answer has been accepted? Yes, of course, if you genuinely believe that you have a better answer. Can you contribute another response (of yours)? It's probably better to edit your original answer. Irrespective of timimg wrt answer acceptance, relevance is importance; amara != lxml. There is a meta-forum for discussion of forums somewhere; it's not here.
John Machin
@John: Are you Rafa Benitez in disguise?
Uche Ogbuji
+2  A: 

With the help of the lxml docs and the dir() built_in, I managed to produce this:

>>> from lxml import objectify
>>> import StringIO
>>> tree = objectify.parse(StringIO.StringIO('<parent><child>Billy</child><child>Bob</child></parent>'))
>>> root = tree.getroot()
>>> root.tag
'parent'
>>> [(foo.tag, foo.text) for foo in root.getchildren()]
[('child', 'Billy'), ('child', 'Bob')]
>>>

Looks like you need something like

deleg = getattr(self,'elem_' + str(root.tag))
deleg(tree)
John Machin