How to select XML child tags and fill a list of dicts with custom keys in a pythonic way

Viewed 147

I'm trying to do some parkour here. Got an exported xml file out of an AccessDB table. I'd like to select just specific tags from each child and save them in a dict, create a list of those dicts and then fill a SQLite custom model database with that list. "Extract and convert"

I managed to parse the XML, get the childs and find the tags and its text. The thing is that it's getting ugly since some childs don't have the tag i'm looking for thus it misses the key but I'd like to default that to "na" and my code is a bit muddy with a lot of if statements under the for loop. I managed to save records in the database with peewee too.

Basically I want to extract data from an AccessDB table, get some field data and save them in a sqlite db with a different field name. I'm running on Linux and I can't get to the AccessDB machine to work with, thus the exported file. If this gets too troublesome I'll try to get the script running there and connect both databases and parse data

xml_parsing_code()

for childs in root:
    for tags in child:
        if tags.tag == 'PM':
            d['maker'] = tags.text
        if ...

    list.append(d)

db.create_code()

I'm not a beginner but still loads to learn and I'm sure I'm missing something, a more "pythonic" simple to write way or there is a simpler easier approach I'm too obtuse to see. I mean, my code works..."sort of", but it's really ugly and patchy and checking for issues in a 6k item list is a bit of a pain.

Thanks a lot!

UPDATE 2: # (made a mistake which I was overwriting missing values and the already filled ones)

import xml.etree.ElementTree as ET

tags_dict = {
    "PartNo": "maker_ref",
    "PM": "maker",
    etc..
}

tree = ET.parse("exported_table.xml")
root = tree.getroot()

dict_list = list()
#d = dict()
for node in root:
    d = dict() #instead of d.clear()
    for child in node:
        for k, v in tags_dict.items():
            if k in child.tag:
                d[v] = child.text
            if v not in d:
                d[v] = "na"

    dict_list.append(d)

This is the final working code for this specific part that seems to do the trick. Added the "na" for the missing childs for my new database model structure.

For some reason I can't figure out why if I declare a global dict() and .clear() it for each node loop, instead of what I posted, it fills my list with the last node data repeated for the whole node count. Anyone can shed some light?

1 Answers

Declare dict for Tag and desired key in your data

desired_tags = {"PM": "maker", etc...}

for child in root:
    for tags in child:
        for k,v in desired_tags.items():
            if k in child.tag:
                d[v] = tags.text

Didnt tested, no posted data estructured.

Related