Question: I have an XML configuration file used by legacy software, which I cannot change or format. The goal is to use Python 3.9 and transform the XML file into a dictionary, using only xml.etree.ElementTree library. I was originally looking at this reply, which produces almost the expected results. Scenario.xml file contents: <Scenario Name="{{ env_name }}"> <Gateways> <Alpha Host="{{ host.alpha_name }}" Order="1"> <Config>{{ CONFIG_DIR }}/alpha.xml</Config> <Arguments>-t1 -t2</Arguments> </Alpha> <Beta Host="{{ host.beta_name }}" Order="2"> <Config>{{ CONFIG_DIR }}/beta.xml</Config> <Arguments>-t1</Arguments> </Beta> <Gamma Host="{{ host.gamma_name }}" Order="3"> <Config>{{ CONFIG_DIR }}/gamma.xml</Config> <Arguments>-t2</Arguments> <!--<Data Count="58" />--> </Gamma> </Gateways> </Scenario>  Python code to convert XML file to dictionary: from pprint import pprint from xml.etree import ElementTree def format_xml_to_dictionary(element: ElementTree.Element): ''' Format xml to dictionary :param element: Tree element :return: Dictionary formatted result ''' try: return { **element.attrib, '#text': element.text.strip(), **{i.tag: format_xml_to_dictionary(i) for i in element} } except ElementTree.ParseError as e: raise e if __name__ == '__main__': tree = ElementTree.parse('Scenario.xml').getroot() scenario = format_xml_to_dictionary(tree) pprint(scenario)  Functional code output with <!--<Data Count="58" />--> commented: $ python test.py {'#text': '', 'Gateways': {'#text': '', 'Alpha': {'#text': '', 'Arguments': {'#text': '-t1 -t2'}, 'Config': {'#text': '{{ CONFIG_DIR }}/alpha.xml'}, 'Host': '{{ host.alpha_name }}', 'Order': '1'}, 'Beta': {'#text': '', 'Arguments': {'#text': '-t1'}, 'Config': {'#text': '{{ CONFIG_DIR }}/beta.xml'}, 'Host': '{{ host.beta_name }}', 'Order': '2'}, 'Gamma': {'#text': '', 'Arguments': {'#text': '-t2'}, 'Config': {'#text': '{{ CONFIG_DIR }}/gamma.xml'}, 'Host': '{{ host.gamma_name }}', 'Order': '3'}}, 'Name': '{{ env_name }}'}  I'm trying to address two issues:  Scenario is missing from dictionary keys, because root node is already the Scenario tag, I'm not sure what I need to do, in order to make it part of dictionary If I uncomment <Data Count="58" />, I get the following error:  AttributeError: 'NoneType' object has no attribute 'strip'  I'm not sure what type of if/else condition I need to implement, I tried something like that, but it is setting all #text values to '' instead of stripping them: '#text': element.text.strip() if isinstance( element.text, ElementTree.Element ) else '', 

Answer: To get Scenario into the result, use tree.tag as the key in the outermost dictionary when calling the function. To handle nodes with no text, add the #text key to the dictionary in a separate statement, so it can be conditional. def format_xml_to_dictionary(element: ElementTree.Element): ''' Format xml to dictionary :param element: Tree element :return: Dictionary formatted result ''' try: result = { **element.attrib, **{i.tag: format_xml_to_dictionary(i) for i in element} } if element.text: result['#text'] = element.text.strip() return result except ElementTree.ParseError as e: raise e if __name__ == '__main__': tree = ElementTree.parse('Scenario.xml').getroot() scenario = { tree.tag: format_xml_to_dictionary(tree) } pprint(scenario)