Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if xml ElementTree node is None/False [duplicate]

Tags:

python

Is it safe to check whether a variable myvar has not-None value by simply:

if myvar:
    print('Not None detected')

I'm asking this because I have a variable and was checking whether the variable was not None by simply if variable: but the check has been failing. The variable contains some data but it was evaluating to False in the if check.

Full Code:

from xml.etree import ElementTree as ElementTree

root = ElementTree.fromstring('Some xml string')

parameters = root.find('Some Tag')

udh = parameters.find('UDH')

if udh and udh.text:  # In this line the check is failing, though the udh variable has value: <Element 'UDH' at 0x7ff614337208>
    udh = udh.text
    # Other code
else:
    print('No UDH!')  # Getting this output
like image 589
Shafiul Avatar asked May 12 '14 07:05

Shafiul


People also ask

How can you tell if node is none?

Use node. isNull() to check if a node is null (not present). Note: The node. isNull() function works with all types of node trees.

What is XML etree ElementTree?

The xml.etree.ElementTree module implements a simple and efficient API for parsing and creating XML data. Changed in version 3.3: This module will use a fast implementation whenever available.

How do you access XML elements in Python?

To read an XML file using ElementTree, firstly, we import the ElementTree class found inside xml library, under the name ET (common convension). Then passed the filename of the xml file to the ElementTree. parse() method, to enable parsing of our xml file. Then got the root (parent tag) of our xml file using getroot().


3 Answers

In Python the boolean (truth) value of the object is not necessarily equal to being None or not. The correctness of that assumption depends on whether your object has the correct methods defined appropriately. As for Python 2.7:

object.__nonzero__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __nonzero__(), all its instances are considered true.

Also have a look at the PEP 8, that provides guidance for this issue (emphasis mine):

Comparisons to singletons like None should always be done with is or is not, never the equality operators.

Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

Therefore, to safely test whether you've got None or not None you should use specifically:

if myvar is None: 
    pass
elif myvar is not None:
    pass

In the case of the xml.etree.ElementTree.Element the semantics of the boolean evaluation differ from the None-ness of the object:

  • Why does bool(xml.etree.ElementTree.Element) evaluate to False?

For reference:

  • https://docs.python.org/2/reference/datamodel.html#object.nonzero
  • http://legacy.python.org/dev/peps/pep-0008/#programming-recommendations
like image 116
moooeeeep Avatar answered Oct 19 '22 10:10

moooeeeep


The ElementTree behaviour for nodes without children is a notorious departure from standard Python practice. In general, it'd be safe to just use the variable in your if condition and assume that the boolean value is sensible. In this case, as you've experienced first hand, you'll have to do a more explicit check.

like image 38
Noufal Ibrahim Avatar answered Oct 19 '22 08:10

Noufal Ibrahim


For your case, it is safe since ElementTree returns False to the __nonzero__ test to check if the element has been found or not.

However, as the doc says, it is better to check explicitly, with is None if you want to check only if the element hasn't been found:

Caution: Because Element objects do not define a nonzero() method, elements with no subelements will test as False.

element = root.find('foo')

if not element: # careful!
    print "element not found, or element has no subelements"

if element is None:
    print "element not found"

For reminder, object.__nonzero__ is used in value testing and in the bool() operation.

like image 2
Maxime Lorant Avatar answered Oct 19 '22 10:10

Maxime Lorant