I have below XML string and trying to convert to DF using below code. In the XML string for each value tag I need them in nested list. Posted the output that I am getting and also sample output of what I am expecting. I am using the below code and might be missing a small logic which I am trying to find out. Can Someone Help me out on what I am missing?
XML String:
xml_str = """
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
<values>
<value>1</value>
<value>5</value>
<value>2</value>
</values>
<values>
<value>3</value>
<value>4</value>
<value>5</value>
</values>
<values>
<value>6</value>
<value>7</value>
<value>8</value>
</values>
</book>
</bookstore>
"""
**Code:**
import xml.etree.ElementTree as ET
import pandas as pd
def attribute_add(el, temp2, tag):
attrib_l = list(el.attrib)
for att in attrib_l:
cur_tag_att = tag + '_' + att
if cur_tag_att in temp2.keys():
if isinstance(temp2[cur_tag_att], list):
temp2[cur_tag_att].append(el.attrib[att])
else:
el_att_list = []
el_att_list.extend([temp2[cur_tag_att], el.attrib[att]])
temp2[cur_tag_att] = el_att_list
else:
temp2[cur_tag_att] = el.attrib[att]
return
def element_loop(element_l, temp1, tag):
"""Input:
element_list
sample_dictionary_variable to write the output to
current xml element tag
Output:
dictionary"""
for el in element_l:
el_tag = []
nested_l = list(el)
new_tag = tag + '_' + el.tag
attribute_add(el, temp1, new_tag)
if len(nested_l) == 0:
if el.text is not None:
if new_tag in temp1.keys():
if isinstance(temp1[new_tag], list):
temp1[new_tag].append(el.text)
else:
el_tag_list = []
el_tag_list.extend([temp1[new_tag], el.text])
temp1[new_tag] = el_tag_list
else:
temp1[new_tag] = el.text
elif len(nested_l) > 0:
element_loop(el, temp1, new_tag)
return temp1
def convert_xml_to_df(xml_str):
"""Input: XML file
Output:
A pandas dataframe with nested xml elements flattened out to individual columns"""
root = ET.fromstring(xml_str)
full_data = []
for ri in root:
temp = {}
attribute_add(ri, temp, ri.tag)
element_l = list(ri)
full_data.append(element_loop(element_l, temp, ri.tag))
df = pd.DataFrame(full_data)
return df
convert_xml_to_df(xml_str)
**Output:**
book_category book_title_lang book_title book_author
0 COOKING en Everyday Italian Giada De Laurentiis
book_year book_price book_values_value
0 2005 30.00 [1, 5, 2, 3, 4, 5, 6, 7, 8]
**Expected Output:**
book_category book_title_lang book_title book_author
0 COOKING en Everyday Italian Giada De Laurentiis
book_year book_price book_values_value
0 2005 30.00 [[1, 5, 2],[ 3, 4, 5], [6, 7, 8]]