1

I'm trying to write my own logic to parse an XML string and convert it into a Python object. It's requiring me to do a bunch of

attribute1 = xml_element.find('ATTRIBUTE1')
attribute2 = xml_element.find('ATTRIBUTE2')

And then several:

if attribute1 is not None:
    obj.attribute1 = attribute1.text
if attribute2 is not None:
    obj.attribute2 = attribute2.text

These multiple if statements (there's almost 50), is causing 4D to show low test coverage (I'm not testing each if statement, obviously) and also say my function has high cognitive complexity. Wondering if there's a way to do this without having multiple if statements? (Third party packages are not an option)

Shiv
  • 332
  • 4
  • 12
  • 2
    What is the logic behind "third party packages are not option"? Parsing XML is a super solved problem. – MrName May 01 '18 at 22:17

1 Answers1

1

You could use a method to check if the object is None

@staticmethod
def assign_attribute(attribute):
    if attribute is not None:
        return attribute.text
    return None

And then simply call it and assign the text or None if the attribute is null:

obj.attribute1 = assign_attribute(attribute1)
obj.attribute2 = assign_attribute(attribute2)

Now you only have one "if" statement.

Edit

This code assumes you are creating and initializing the object from your XML for the first time, if obj.attribute1 already contains a value and then you use the assign_attribute method and the attribute is None, the original value will be cleared.

If you want to keep existing values, then the method could be something like this:

@staticmethod
def assign_attribute(xml, attribute_name, current_value):
    attribute = xml.find(attribute_name)
    if attribute is not None:
        return attribute.text
    elif current_value is not None:
        return current_value
    else
        return None

obj.attribute1 = assign_attribute(xml_element, 'ATTRIBUTE1', obj.attribute1)
obj.attribute2 = assign_attribute(xml_element, 'ATTRIBUTE2', obj.attribute2)
Isma
  • 14,604
  • 5
  • 37
  • 51
  • 1
    This would assign `None` to `obj.attribute`, which is not quite the same as not assigning – Andomar May 01 '18 at 22:01
  • @Andomar, really? I thought all objects were None by default in Python. What is the difference between None and "not assigned"? – Isma May 01 '18 at 22:13
  • Say that `obj.attribute1` is equal to `"apple"` and `attribute1` is `None`, then your code will change `"apple"` to `None`, while the original code would leave it at `"apple"` – Andomar May 01 '18 at 22:15
  • Ah, I get you. Of course, I assumed he is creating and initializing the object for the first time using XML, I will add this to the answer. Thanks... – Isma May 01 '18 at 22:17