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.
CodePudding user response:
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")
CodePudding user response:
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.
CodePudding user response:
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'))