HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonMinor

Parse and write data from/to a xml file

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filewriteparsexmlandfromdata

Problem

I recently started to learn Python for the purpose of making my life as a network engineer easier when performing repetitive tasks.

The script below does parse a huge inventory.xml file I get from a reporting tool to find the ID of ports I want it to and then writes back to the XML file a structure representing a cable between the two network ports. I do convey the name of the ports I want to link in a basic CVS file with 2 columns.

                                                                                                                                              
ca1cfd39-cf8f-4d69-a52b-d06357da66b1                                                                                             
79d8c32a-8891-4bd4-a0a1-1a6e1b333a4b                                                                                             


This is the code I tried to comment to the best of my ability:

```
#links.csv file shoud be made as follows :
#port1,port2
#port1,port2
# .
# .
# .
from lxml import etree
import csv
import fileinput

#preparing variables
result=[]
trigger=False
tree=etree.parse("inventory.xml")

#parsing the csv file containing the port names to link together
with open('links.csv', 'rb') as csvfile:
fichier=csv.reader(csvfile)
for row in fichier:
name1=row[0] #name of the first port
name2=row[1]
portid1=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
portid2=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))
portid1=portid1[2:-2] #output was surrounded by [""] so i cut the first two and last two
portid2=portid2[2:-2]
result.append(("\n{}\n{}\n\n").format(portid1, portid2)) #store data

result="".join(result)
#search the file until we find the line, then we print the result
for line in fileinput.input('inventory.xml', inplace=1):
if line.startswith(' '):
trigger=True
else:
if tri

Solution

I don't know anything about phyton, but I will throw my 5 ct in anyway.

Adding horizontal spaces between assignments to variables/properties and vertical spacing between related parts will make your code more readable like so

for row in fichier:
        name1 = row[0] #name of the first port
        name2 = row[1] 

        portid1 = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
        portid2 = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))

        portid1 = portid1[2:-2] #output was surrounded by [""] so i cut the first two and last two
        portid2 = portid2[2:-2]

        result.append(("\n{}\n{}\n\n").format(portid1, portid2)) #store data


If you need a comment about a variable, then this variable is poorly named. So better name the variable in a meaningful name and remove the comment.

name1=row[0] #name of the first port
name2=row[1]


vs.

first_port_name = row[0]
second_port_name = row[1]


The same approach I would use for

portid1=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
portid2=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))


like so

first_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
second_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))


So the mentioned points together would look like so

for row in fichier:
        first_port_name = row[0]
        second_port_name = row[1] 

        first_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
        second_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))

        first_port_id = first_port_id[2:-2] #output was surrounded by [""] so i cut the first two and last two
        second_port_id = second_port_id[2:-2]

        result.append(("\n{}\n{}\n\n").format(first_port_id , second_port_id )) #store data

Code Snippets

for row in fichier:
        name1 = row[0] #name of the first port
        name2 = row[1] 

        portid1 = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
        portid2 = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))

        portid1 = portid1[2:-2] #output was surrounded by [""] so i cut the first two and last two
        portid2 = portid2[2:-2]

        result.append(("<link>\n<portid1>{}</portid1>\n<portid2>{}</portid2>\n</link>\n").format(portid1, portid2)) #store data
name1=row[0] #name of the first port
name2=row[1]
first_port_name = row[0]
second_port_name = row[1]
portid1=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
portid2=str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))
first_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name1)) #searches for the port id in the .xml
second_port_id = str(tree.xpath("//name[text()='%s']/parent::*/id/text()" %name2))

Context

StackExchange Code Review Q#96097, answer score: 5

Revisions (0)

No revisions yet.