Я пытаюсь преобразовать файл xml в кадры данных для добавления в словарь. Ниже приведена структура
<id =123>
<table_group>
<table_1>
<col_heading1>value1</col_heading1>
<col_heading2>value2</col_heading2>
<col_heading3>value3</col_heading3>
</table_1>
<table_2>
<col_heading1> value1 </col_heading1>
<col_heading2> value2 </col_heading2>
<col_heading3>
<sub_col_heading1> value3 </sub_col_heading1>
</col_heading3>
</table_2>
</table_group>
</id>
<id =124>
<table_group>
<table_1>
<col_heading1>value1</col_heading1>
<col_heading2>value2</col_heading2>
<col_heading3>value3</col_heading3>
</table_1>
<table_2>
<col_heading1> value1 </col_heading1>
<col_heading2> value2 </col_heading2>
<col_heading3>
<sub_col_heading1> value3 </sub_col_heading1>
</col_heading3>
</table_2>
</table_group>
</id>
Это тяжелый файл с несколькими таблицами с несколькими столбцами в нескольких группах таблиц для нескольких идентификаторов.
Я хочу создать гибкий oop для каждой таблицы создать фрейм данных для каждой таблицы, добавив каждый идентификатор и соответствующие значения для этой таблицы. Тем не менее, некоторые таблицы имеют более одного уровня или дочерний, где их значение должно быть. Смотрите table_2, col_heading3. У этого узла есть дочерний элемент sub_col_heading1. Я создал код, который работает, если ожидаемый столбец col_heading имеет только один дополнительный уровень, но я заметил, что в некоторых таблицах более одного уровня.
Этот код работает для одной таблицы, в идеале, если бы она была более гибкой, я могу l oop через несколько таблиц, однако каждая из них имеет свою структуру, и их дочерние элементы могут иметь более одного уровня.
import pandas as pd
import xml.etree.ElementTree as ET
tree = ET.parse('xml')
root = tree.getroot()
dffx = pd.DataFrame() #empty dataframe to be filled with parsed XML data for one table
for ids in range(len(root[1].getchildren())): #loops for all the ids in the xml file, about 12000 total.
data =[]
cols = [] #should be the column heading
values = [] #holds the values for the respective col_heading, to be zipped into a dictionary
dff1 = pd.DataFrame(data) #create a temp dataframe
cols.append('InstrumentId') #adds the ID into the dataframe, as the table does not include it
values = [str(root[1][ids].attrib)[8:-2]] #isolates the id number as it is an attrib
for i in root[1][ids][0][0].getchildren():#ideally this would be looped as for table root[1][ids][0][table].getchildren(), but root[1][ids][table_group][table2].getchildren() is for one table right now.
if i.text == '\n ': # .text should be the value, if i does not have value that means it needs to go down another level
for x in i.getchildren(): #next level under i, if there is another level then x.text = \n and needs to go down another level, for the same if logic
cols.append(x.tag) #grab field name
values.append(x.text) #grab value
cols.append(i.tag) #grab parent field name
values.append(x.tag) #make parent value = child field name, this logic should apply the more levels down, adding the parent.tag as the child value if another level needs to be added
else:
cols.append(i.tag) # if only one level then field name
values.append(i.text) #value
data.append(dict(zip(cols,values)))
dff1 = dff1.append(data, ignore_index= False)
dffx= dffx.append(dff1)
Вложенный оператор if - это то, что я хочу сделать бесконечным условным l oop. Если первый уровень не имеет текстового значения, но имеет дочерние элементы, получает дочерние значения и присваивает родительскому значению дочернее имя, если дочерний элемент не имеет значений, но внуки получают значения внуков, присвойте дочернему значению имя внука и т. Д. c и c.