1

I am new to python and wrote:

root = ET.fromstring(xml_output)
host = root.find('host')
if host:
    ports = host.find('ports')
    if ports:
        for port in ports:
            service = port.find('service')
            if service:
                print(service.attrib.get('name'))

My code works find but it looks very ugly, how can I solve this? It's going too much deep that it's hard to read, plus what If I want to add other fields under name? that will be terrible code design.

3
  • 4
    you don't need if ports: if ports is empty it just won't loop Commented Nov 2, 2021 at 7:30
  • @Tranbi any more suggestions? Commented Nov 2, 2021 at 7:33
  • Deleted the xml tag, this question has nothing to do with XML. Commented Nov 2, 2021 at 11:16

3 Answers 3

1

I think the important part for you is the last print statement. If this is the case, then you could put the things in a try, except block. Depending on what you want to know about where it failed you have to make this code a bit more detailed.

root = ET.fromstring(xml_output)
try:
    host = root.find('host')  
    ports = host.find('ports')
    for port in ports:
        service = port.find('service')
        print(service.attrib.get('name'))
catch:
    print("Something did not connect")
Sign up to request clarification or add additional context in comments.

Comments

1

one alternative to nested ifs is using guard clauses:

root = ET.fromstring(xml_output)
host = root.find('host')
if not host:
    return
ports = host.find('ports')
if not ports:
    return
for port in ports:
    service = port.find('service')
    if not service:
        continue
    print(service.attrib.get('name'))

Also, in your case if ports are empty or None it will NOT loop through ports, so insted of:

if ports:
    for port in ports:
        service = port.find('service')
        if service:
            print(service.attrib.get('name'))

just:

for port in ports:
    service = port.find('service')
    if service:
       print(service.attrib.get('name'))

would suffice.

Comments

1

Since what you're really doing is to print the name attribute of all service nodes under a ports node under a host node, you can find the said nodes with one call to the iterfind method with a proper XPath expression instead:

for service in ET.fromstring(xml_output).iterfind('.//host//ports//service'):
    print(service.attrib.get('name'))

1 Comment

It didn't do the same job

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.