Home > Enterprise >  Python large xml to dataframe
Python large xml to dataframe

Time:09-17

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... 
  • Related