Andrew Channels Dexter Pinion

Wherein I write some stuff that you may like to read. Or not, its up to you really.

October 21, 2004

Resolving Interesting Behaviour in Element Tree

Update: This isn't actually a problem. The code samples given below perform as expected (i.e. none of the print statements produce any output) when run on current Python releases. I made a mistake when cutting and pasting my sample code, many apologies and thanks to Fredrik and zgoda for pointing this out in the nicest possible way.

Many thanks to all of the people who read and commented on my previous post about ElementTree. As Fredrik said, replacing if child2: with if child2 is not None: meant that the code worked as I intended. I'm now a happy programmer.

But, and you knew there was going to be a but, I'm intrigued by the apparently disparate behaviour exhibited by what seems to be the same piece of code in two slightly different places. My if statement worked as expected when used against a single element but did something different when included within a for loop which examined each of the elements in turn.

I feel another interactive session coming on. Using the same XML file as my previous post;

>>> from elementtree import ElementTree
>>> tree = ElementTree.parse("wibble.xml")
>>> root = tree.getroot()
>>> wobble = root[0]
>>> child2 = wobble.find("child2")
>>> if child2:
...      print child2.text.strip()
...
Child value 2
>>> wobble = root[1]
>>> child2 = wobble.find("child2")
>>> if child2:
...      print child2.text.strip()
...
>>>

So far, so good. Even though I'm using if child2: I get my expected result as the first child node of our root does have a child2 sub element. But putting the same snippet of code within a for loop and, essentially, executing the previous code within one block gives a different output;

>>> for wobble in root:
...      child2 = wobble.find("child2")
...      if child2:
...          print child2.text.strip()
...
>>>

Even though the first element in the sequence has a child2 sub element nothing is printed out this time - unlike the first example. If I replace the if child2: statements with if child2 is not None: then I consistently get the results I expect. But that isn't the point of this post. In the first snippet I get my expected behaviour, but in the second I don't. My point here is that I get different results from within a for loop than when I examine the elements in series.

This must mean that the first interactive session, even though it's giving me what I expect, is actually providing incorrect results. Surely this is a bug? Or am I being obtuse again?

Posted by Andy Todd at October 21, 2004 12:32 AM

Comments

works for me:

>>> from elementtree import ElementTree
>>> tree = ElementTree.parse("wibble.xml")
>>> root = tree.getroot()
>>> wobble = root[0]
>>> child2 = wobble.find("child2")
>>> if child2:
... print child2.text.strip()
...
>>>

>>> child2
<Element child2 at a30378>
>>> child2.text
'\n Child value 2\n '

what Python version are you using, and what platform are you running on? are you using a plain Python interpreter, or some IPython/IDLE thingie?

(if this is a bug, I doubt it's in ElementTree. Python code usually works the same no matter how you run it...)

Posted by: Fredrik on October 21, 2004 08:20 AM

Confirmed: works as Fredrik wrote (Python 2.3.4 on Windows).

Posted by: zgoda on October 21, 2004 09:57 AM

Sorry folks, my fault. I cut and past the code incorrectly. It's working as Fredrik said on my Mac (running Python 2.3.0). I blame the jet lag ;-)

Posted by: Andy Todd on October 22, 2004 12:41 AM