Search code examples
pythonxml

Simplify None Check without Repeating XML Path


I'm trying to parse out some XML, where some tags aren't always in the XML. I was getting an error when trying to get the text, as I can't get .text when it's None

Seems like there should be a better way to handle this? This is also just one value, I have many that I need to extract I don't think repeating the XML Path is great solution

This returns "" if value is None and returns the actual text if exists:

myArr.append([
"" if properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id1", namespaces) is None else properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id1", namespaces).text,
"" if properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id2", namespaces) is None else properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id2", namespaces).text,
"" if properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id3", namespaces) is None else properties.find("link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id3", namespaces).text
(... many more ...)
])

Solution

  • Just write yourself a small utility function:

    def get_xpath_value(xmlel, xpath, namespaces={}, fallback=""):
        if (el := xmlel.find(xpath, namespaces)) is not None:
            return el.text
        else:
            return fallback
    
    value = get_xpath_value(properties, "link[@title='myTitle']/a:inline/feed/entry/content/b:properties/c:Id", namespaces=namespaces)