0

I need some help with an iteration. My root in XML is sdnEntry. If i use [0] without any iteration in the doc, i can retrieve the text value from it, but when i am doing the loop i receive errors like "last_names = sdns.getElementsByTagName("lastName"). AttributeError: 'NodeList' object has no attribute 'getElementsByTagName'"

My working code- wihout any iteration looks like this:

from xml.dom import minidom
xmldoc = minidom.parse("/Users/cohen/Documents/project/sdn.xml")
sdns = xmldoc.getElementsByTagName("sdnEntry")[0]
last_names = sdns.getElementsByTagName("lastName")[0]
ln = last_names.firstChild.data
types = sdns.getElementsByTagName("sdnType")[0]
t = types.firstChild.data


programs = sdns.getElementsByTagName("programList")[0] #program.firstChild.data
s = programs.getElementsByTagName("program")[0].firstChild.data
akas = sdns.getElementsByTagName("akaList")[0] #child lastName.fourthChild.data
a = akas.getElementsByTagName("aka")[0]
a1 = a.getElementsByTagName("lastName")[0].firstChild.data

addresses = sdns.getElementsByTagName("addressList")[0]
ad1 = addresses.getElementsByTagName("address")[0]
ad2 = ad1.getElementsByTagName("city")[0]
city= ad2.firstChild.data
ad3 = ad1.getElementsByTagName("country")[0]
country = ad3.firstChild.data

This is how it looks like my XML:

<sdnEntry>
    <uid>36</uid>
    <lastName>AEROCARIBBEAN AIRLINES</lastName>
    <sdnType>Entity</sdnType>
    <programList>
      <program>CUBA</program>
    </programList>
    <akaList>
      <aka>
        <uid>12</uid>
        <type>a.k.a.</type>
        <category>strong</category>
        <lastName>AERO-CARIBBEAN</lastName>
      </aka>
    </akaList>
    <addressList>
      <address>
        <uid>25</uid>
        <city>Havana</city>
        <country>Cuba</country>
      </address>
    </addressList>
  </sdnEntry>

Below is my for loop. Please advise. Thank you in advance!

for sdn in sdns:
    for ln in last_names:
        print(ln)
        for t in types:
            print(t)
            for program in programs:
                print (s)
                for aka in akas:
                    print(a1)
                    for address in addresses:
                        print(city)
                        print(country)

I need to store each sdnEntry in my DB, therefore i need for each entry to know only the

  • <name> (lastName AEROCARIBBEAN AIRLINES),
  • <sdnType> (Entity)`,
  • <programs> from program list e.g. (program CUBA) but they can be more,
  • <aka><lastName> (AERO-CARIBBEAN) all of them
  • <address> all of them (city Havana country Cuba )

How can I do that?

2 Answers 2

1
from xml.etree import ElementTree

# I included this list to help
all_nodes = ['sdnEntry', 'uid', 'lastName', 'sdnType', 'programList', 'program', 'akaList',
             'aka', 'uid', 'type', 'category', 'lastName', 'addressList', 'address', 'uid',
             'city', 'country']

required_nodes = ['lastName', 'uid', 'program', 'type', 'category', 'city', 'country']

# required because some names are repeated uid, last
keys = ['sdnEntry_uid', 'lastName', 'program', 'aka_uid', 'type', 'category', 'aka_lastName',
        'address_uid', 'city', 'country']

sdn_data = {}
index = 0

with open('stuff.xml', 'r') as xml_file:
    tree = ElementTree.parse(xml_file)

# iterate all nodes
for node in tree.iter():
    # check if a required node
    if node.tag in required_nodes:
        # add to dictionary
        sdn_data[keys[index]] = node.text
        index += 1

# Use this to test
for key, value in sdn_data.items():
    print(key, value)

output
sdnEntry_uid 36
lastName AEROCARIBBEAN AIRLINES
program CUBA
aka_uid 12
type a.k.a.
category strong
aka_lastName AERO-CARIBBEAN
address_uid 25
city Havana
country Cuba

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer! that is a step forward. I need to store each sdnEntry in my DB, therefore i need for each entry to know only the name (lastName AEROCARIBBEAN AIRLINES), (sdnType Entity), programs from program list e.g. (program CUBA) but they can be more, all of the akas (lastName AERO-CARIBBEAN) and all the addresses ( city Havana country Cuba ) how i can do that? Thank you Diek!
Updated code, it can be easily modified to remove an item not needed
The above logic should work, it was done for one entry. Reset the index to 0 after each complete entry
0

Not really an answer, but may I suggest trying out xmltodict. The API is much easier to deal with IMO, and if you do hit errors, they will definitely be less cryptic (i.e. - since the full result payload is just a python dict, it is easy to look through and see where things might have gone wrong).

1 Comment

Thanks! maybe because they are seeing like lists and have no text attribute?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.