Home > Back-end >  Parse XML file with Python xml.dom.minidom
Parse XML file with Python xml.dom.minidom

Time:12-27

I am trying to parse a XML file with python for a school project.

To see if the prasing works I printed the values of the "lista_marfuri".

It shows the following error: xml.parsers.expat.ExpatError: XML declaration not well-formed: line 1, column 35

The XML code is:

<?xml version="1.0" encoding="UTF-8 standalone="yes"?>

<fapte>
    <lista_marfuri>
        <marfa> 
            <id> 1 </id>
            <nume> grebla </nume>
            <categorie> gradinarit </gradinarit>
            <cantitate> 100 </cantitate>
            <pret> 20 </pret>
        </marfa>
        <marfa> 
            <id> 2 </id>
            <nume> sac 1kg ingrasamant </nume>
            <categorie> gradinarit </gradinarit>
            <cantitate> 300 </cantitate>
            <pret> 30 </pret>
        </marfa>
        <marfa> 
            <id> 3 </id>
            <nume> surubelnita </nume>
            <categorie> general </gradinarit>
            <cantitate> 200 </cantitate>
            <pret> 5 </pret>
        </marfa>
    </lista_marfuri>
    
    
    <lista_categorii>
        ...
    </lista_categorii>
    
    <lista_clienti>
        ...
    </lista_clienti>
    
    <lista_comenzi>
        ...
    </lista_comenzi>
    
</fapte>

And the python code is:

import xml.dom.minidom

tree = xml.dom.minidom.parse('SBC.xml')

fapte = tree.documentElement

marfuri = fapte.getElementsByTagName('marfa')

for marfa in marfuri:
    print(f"-- Marfa {marfa.getAttribute('id')} --")

    nume = marfa.getElementByTagName('nume')[0].childNodes[0].nodeValue
    categorie = marfa.getElementByTagName('categorie')[0].childNodes[0].nodeValue
    cantitate = marfa.getElementByTagName('cantitate')[0].childNodes[0].nodeValue
    pret = marfa.getElementByTagName('pret')[0].childNodes[0].nodeValue

    print(f"Nume: {nume}")
    print(f"Categorie: {categorie}")
    print(f"Cantitate: {cantitate}")
    print(f"Pret: {pret}")

CodePudding user response:

I think working with ElementTree will make your life easier.

import xml.etree.ElementTree as ET

xml = '''<fapte>
    <lista_marfuri>
        <marfa> 
            <id> 1 </id>
            <nume> grebla </nume>
            <categorie> gradinarit </categorie>
            <cantitate> 100 </cantitate>
            <pret> 20 </pret>
        </marfa>
        <marfa> 
            <id> 2 </id>
            <nume> sac 1kg ingrasamant </nume>
            <categorie> gradinarit </categorie>
            <cantitate> 300 </cantitate>
            <pret> 30 </pret>
        </marfa>
        <marfa> 
            <id> 3 </id>
            <nume> surubelnita </nume>
            <categorie> general </categorie>
            <cantitate> 200 </cantitate>
            <pret> 5 </pret>
        </marfa>
    </lista_marfuri>
</fapte>'''

root = ET.fromstring(xml)
for marfa in root.findall('.//marfa'):
    for entry in marfa:
        print(f'{entry.tag} : {entry.text.strip()}')
    print('------------------')

output

id : 1
nume : grebla
categorie : gradinarit
cantitate : 100
pret : 20
------------------
id : 2
nume : sac 1kg ingrasamant
categorie : gradinarit
cantitate : 300
pret : 30
------------------
id : 3
nume : surubelnita
categorie : general
cantitate : 200
pret : 5
------------------

CodePudding user response:

If the xml is valid, correct closing in the first line and the closing tag of <\categories> as @mzjn noted (this shows also your Error message), than it’s the shortest to use pandas read_xml():

import pandas as pd

df = pd.read_xml('yourFileName.xml', xpath='.//marfa')
print(df)

Output:

   id                 nume   categorie  cantitate  pret
0   1               grebla  gradinarit        100    20
1   2  sac 1kg ingrasamant  gradinarit        300    30
2   3          surubelnita     general        200     5

PS: This works only, if all your interested values are on the same level in the tree.

  • Related