Coverage for pyguymer3/elem2dict.py: 81%

26 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def elem2dict( 

5 elem, 

6 /, 

7 *, 

8 debug = __debug__, 

9): 

10 """Convert a XML element into a Python dictionary 

11 

12 This function accepts a XML element and recursively turns it in to a Python 

13 dictionary. 

14 

15 Parameters 

16 ---------- 

17 elem : lxml.etree._Element 

18 the XML element 

19 debug : bool, optional 

20 print debug messages 

21 

22 Returns 

23 ------- 

24 ans : dict 

25 the XML element as a Python dictionary 

26 

27 Notes 

28 ----- 

29 If present, non-empty text will be mapped to a "$$TEXT$$" dictionary field 

30 (it is assumed that the XML does not contain any tags called "$$TEXT$$" 

31 otherwise). If present, non-empty attributes will be mapped to "::KEY::" 

32 dictionary fields (it is assumed that the XML does not contain any tags 

33 called "::KEY::" otherwise). If present, child elements will be mapped to 

34 "KEY" dictionary fields. If multiple child elements have identical tag names 

35 then the "KEY" dictionary field will be a list of them. 

36 

37 Copyright 2017 Thomas Guymer [1]_ 

38 

39 References 

40 ---------- 

41 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

42 """ 

43 

44 # Initialize dictionary ... 

45 ans = {} 

46 

47 # Check if it has text ... 

48 if elem.text: 

49 # Check that the text isn't empty ... 

50 if elem.text.strip(): 

51 ans["$$TEXT$$"] = elem.text 

52 elif debug: 

53 print(f"INFO: Skipping empty text in \"{elem.tag}\".") 

54 

55 # Loop over attributes ... 

56 for key, value in elem.attrib.iteritems(): 

57 # Check that the attribute isn't empty ... 

58 if value.strip(): 

59 # Check if the attribute can be dealt with specially ... 

60 if value.isdigit(): 

61 ans[f"::{key}::"] = int(value) 

62 elif value.lower() == "true": 

63 ans[f"::{key}::"] = True 

64 elif value.lower() == "false": 

65 ans[f"::{key}::"] = False 

66 else: 

67 ans[f"::{key}::"] = value 

68 elif debug: 

69 print(f"INFO: Skipping empty \"{key}\" attribute in \"{elem.tag}\".") 

70 

71 # Loop over children ... 

72 for child in elem.iterchildren(): 

73 # Convert child to a dictionary ... 

74 value = elem2dict(child, debug = debug) 

75 

76 # Check if a field already exists ... 

77 if child.tag in ans: 

78 # Check if the field is already a list ... 

79 if isinstance(ans[child.tag], list): 

80 # Append to list ... 

81 ans[child.tag].append(value) 

82 else: 

83 # Convert the field to a list ... 

84 ans[child.tag] = [ans[child.tag], value] 

85 else: 

86 # Set field ... 

87 ans[child.tag] = value 

88 

89 # Return answer ... 

90 return ans