I am trying to transform a large xml file into a dataframe. Here is a sample:
<?xml version='1.0' encoding='UTF-8'?>
<compteRendu xmlns="http://schemas.assemblee-nationale.fr/referentiel">
<uid>CRSANR5L15S2017E1N001</uid>
<metadonnees>
<day>04 juillet 2017</day>
<legislature>15</legislature>
<sommaire>
<president id_syceron="981337">Présidence de M. François de Rugy</president>
</sommaire>
</metadonnees>
<contenu>
<quantiemes>
<journee>Séance du mardi 04 juillet 2017</journee>
<session>Première session extraordinaire 2017</session>
</quantiemes>
<point nivpoint="1" valeur_ptsodj="2" ordinal_prise="1" id_preparation="819547" ordre_absolu_seance="8" code_grammaire="TITRE_TEXTE_DISCUSSION" code_style="Titre" code_parole="" sommaire="1" id_syceron="981344" valeur="">
<orateurs/>
<texte>Déclaration de...</texte>
<paragraphe valeur_ptsodj="2" ordinal_prise="1" id_preparation="819550" ordre_absolu_seance="11" id_acteur="PA345619" id_mandat="-1" id_nomination_oe="PM725692" id_nomination_op="-1" code_grammaire="DEBAT_1_10" code_style="NORMAL" code_parole="PAROLE_1_2" sommaire="1" id_syceron="981347" valeur="">
<orateurs>
<orateur>
<nom>M. Edouard Philippe</nom>
<id>345619</id>
<qualite>Premier ministre</qualite>
</orateur>
</orateurs>
<texte>Monsieur le président... <italique>(Applaudissements sur les bancs des groupes REM et MODEM.)</italique></texte>
</paragraphe>
</point>
</contenu>
</compteRendu>
Dataframe that I want to obtain:
day legislature texte nom texte2
04 juillet 2017 15 Déclaration de... Edouard Philippe Monsieur le president...
My code so far:
import pandas as pd
import xml.etree.ElementTree as et
etree=et.parse("myfile.xml")
root=etree.getroot()
A=[]
for ele in root:
B={}
for i in list(ele):
B.update({i.tag: i.text})
A.append(B)
df=pd.DataFrame(A)
Dataframe that I am obtaining incorrectly:
day legislature sommaire quantiemes point
04 juillet 2017 15 \n NaN NaN
How I should change my code?
CodePudding user response:
Maybe something like this.
Edit: I've added another <nom>
and another <texte>
to myfile.xml
. "Increment" for duplicates should work now. Expecting: nom
, nom2
, and texte
, texte2
, texte3
.
Code
import pandas as pd
import xml.etree.ElementTree as ET
tree = ET.parse('myfile.xml')
root = tree.getroot()
# create a dict with first childs as key and descendants as values
d = {'metadonnees':['day','legislature'],
'contenu':['nom','texte']}
# initialize two lists: `cols` and `data`
cols, data = list(), list()
# loop through d.items
for k, v in d.items():
# find child
child = root.find(f'{{*}}{k}')
# use iter to check each descendant (`elem`)
for elem in child.iter():
# get `tag_end` for each descendant,
# e.g. `texte` in
#"{http://schemas.assemblee-nationale.fr/referentiel}texte"
tag_end = elem.tag.split('}')[-1]
# check if `tag_end` in `v(alue)`
if tag_end in v:
# add `tag_end` and `elem.text` to appropriate list
cols.append(tag_end)
data.append(elem.text)
df = pd.DataFrame(data).T
# helper function to "increment" duplicate col names
# see: https://stackoverflow.com/a/70830702/18470692
def f(lst):
d = {}
out = []
for i in lst:
if i not in d:
out.append(i)
d[i] = 2
else:
out.append(i str(d[i]))
d[i] = 1
return out
df.columns = f(cols)
Result:
print(df.T)
0
day 04 juillet 2017
legislature 15
texte Déclaration de...
nom M. Edouard Philippe
nom2 M. Edouard Philippe 2
texte2 Monsieur le président...
texte3 Monsieur le président 2...