views:

66

answers:

1

So I gotta deal with some xml that looks like this:

<ns2:foobarResponse xmlns:ns2="http://api.example.com"&gt;
  <duration>206</duration>
  <artist>
    <tracks>...</tracks>
  </artist>
</ns2:foobarResponse>

I found lxml and it's objectify module, that lets you traverse a xml document in a pythonic way, like a dictionary.
Problem is: it's using the bogus xml namespace every time you try to access an element, like this:

from lxml import objectify

tree = objectify.fromstring(xml)
print tree.artist
# ERROR: no such child: {http://api.example.com}artist

It's trying to access <artist> with the parent namespace, but the tag doesn't use the ns.

Any ideas how to get around this? Thanks

+1  A: 

According to the lxml.objectify documentation, attribute lookups default to using the namespace of their parent element.

What you probably want to work would be:

print tree["{}artist"]

QName syntax like this would work if your children had a non-empty namespace ("{http://foo/}artist", for instance), but unfortunately, it looks like the current source code treats an empty namespace as no namespace, so all of objectify's lookup goodness will helpfully replace the empty namespace with the parent namespace, and you're out of luck.

This is either a bug ("{}artist" should work), or an enhancement request to file for the lxml folks.

For the moment, the best thing to do is probably:

print tree.xpath("artist")

It's unclear to me how much of a performance hit you'll take using xpath here, but this certainly works.

Jeffrey Harris