I have following xml data in string format, which using lxml package of python, I am parsing into xml.
Now, I have to traverse through this xml data and generate an output in a specific format which will be something like this
<A xmlns="dfjdlfkdjflsd">
<B>
<B1>B_1</B1>
<B2>B_2</B2>
<B3>
<B31>B3_1</B31>
<B32>B3_2</B32>
<B33>
<B331>
<B3311></B3311>
</B331>
<B332>
<B3321></B3321>
</B332>
</B33>
<B34>
<B341>
<B3411></B3411>
</B341>
<B342>
<B3421></B3421>
</B342>
</B34>
<B35>
<B351>B35_1</B351>
<B352>
<B3521>
<B35211></B35211>
<B35211></B35212>
</B3521>
</B352>
</B35>
<B36>
<B361>B36_1</B361>
<B362>B36_2</B362>
</B36>
</B3>
</B>
</A>
And I would like to have the output in the following format:
{
'B1': 'B_1',
'B2': 'B_2',
'B3_B31': 'B3_1',
'B3_B32': 'B3_2',
'B3_B33_B331_B3311': '-',
'B3_B33_B331_B3312': '-',
'B3_B34_B341_B3411': '-',
'B3_B34_B342_B3421': '-',
'B3_B35_B351': 'B35_1',
'B3_B35_B352_B3521_B35211': '-',
'B3_B35_B352_B3521_B35212': '-',
'B3_B36_B361': 'b36_1',
'B3_B36_B361': 'B36_2',
}
Now, this is just an EXAMPLE. In real scenario, depth of each xml tag might be different. So, I decided to use the recursive approach. And this is so far I have came in terms of code:
class ParseXML:
main_output = []
output = {}
def __init__(self, xml_input):
parser = ET.XMLParser(recover=True)
tree = ET.ElementTree(ET.fromstring(xml_input, parser=parser))
self.root = tree.getroot()
def parse_outer_xml(self):
for children in self.root:
output = self.parse_xml(children, output={})
self.main_output.append(output)
return self.main_output
def parse_xml(self, children, tag=None, output={}):
if len(children):
for child in children.getchildren():
if child.tag.split('}')[1] in GLOBAL_DICT:
output['{0}_{1}'.format(tag, child.tag.split('}')[1]) if tag else child.tag.split('}')[1]] = child.text
else:
if child.tag.split('}')[1] not in GLOBAL_EXCLUDE_DICT:
if len(child):
if children.tag.split('}')[1] == 'B':
tag = child.tag.split('}')[1]
else:
tag = "{0}_{1}".format(tag, child.tag.split('}')[1]) if tag else "{0}_{1}".format(children.tag.split('}')[1], child.tag.split('}')[1])
return self.parse_xml(child, tag, output)
else:
output['{0}_{1}'.format(tag, child.tag.split('}')[1]) if tag else child.tag.split('}')[1]] = child.text if child.text else "-"
else:
output['{0}_{1}'.format(tag, children.tag.split('}')[1]) if tag else children.tag.split('}')[1]] = children.text if children.text else "-"
return output
if __name__ == '__main__':
parse = ParseXML(data)
temp = parse.parse_outer_xml()
pprint(temp)
I am getting this output when I run
[{'B1': 'B_1',
'B2': 'B_2',
'B3_B31': 'B3_1',
'B3_B32': 'B3_2',
'B3_B33_B331_B3311': '-'}]
But this code does not traverse to full depth. Can anyone look into this and provide some guidance on how to traverse through this xml data till full depth.