bman87
asked on
Create XML from python script
I need to generate an xml file of this form from a python script:
<?xml version="1.0" encoding="UTF-8"?>
<hosts>
<host>
<name>Computer1</name>
<ip>127.0.0.1</ip>
<scan>03/04/2009</scan>
<config>test.conf</config>
<enabled>yes</enabled>
</host>
<host>
<name>Computer2</name>
<ip>127.0.0.1</ip>
<scan>03/04/2009</scan>
<config>test.conf</config>
<enabled>yes</enabled>
</host>
</hosts>
For a simple structure like this, you can just write it as a text file. In what form do you have the data? In a database, in a list of dictionaries, list of tuples, list of objects or something else?
ASKER
actually what i am planning on doing is scanning a directory which has this structure:
Computers (top level folder)
|---Computer1 (folder)
|----Dir1 (folder)
|----Dir2 (folder)
|----settings.conf (config file)
|---Computer2 (folder)
|----Dir1 (folder)
|----Dir2 (folder)
|----settings.conf (config file)
Where there is a seperate folder for each computer. Inside each folder, there is a settings file which is of the format:
name = computer1
ip = 127.0.0.1
....
i basically want to go to each one of these files, and append it to the xml file.
Computers (top level folder)
|---Computer1 (folder)
|----Dir1 (folder)
|----Dir2 (folder)
|----settings.conf (config file)
|---Computer2 (folder)
|----Dir1 (folder)
|----Dir2 (folder)
|----settings.conf (config file)
Where there is a seperate folder for each computer. Inside each folder, there is a settings file which is of the format:
name = computer1
ip = 127.0.0.1
....
i basically want to go to each one of these files, and append it to the xml file.
ASKER
i forgot to mention that there are many settings in this settings.conf file, and i only want the ones specified in the xml file
To fetch the files, use glob:
import glob
files = glob.glob('Computers/*/set tings.conf ')
Loop over the files like this:
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
print MakeXml(settings)
GetSettings() makes a dictionary from the content of the file, makeXml() creates the XML "record". I don't know if these settings files have comments, I inserted a mechanism to allow for standard # line comments, see below. Instead of printing it, you can write it to a file:
xml = open('Settings.xml','w');
xml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
xml.write('<hosts>\n');
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
xml.write(MakeXml(settings ))
xml.write('</hosts>');
xml.close()
import glob
files = glob.glob('Computers/*/set
Loop over the files like this:
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
print MakeXml(settings)
GetSettings() makes a dictionary from the content of the file, makeXml() creates the XML "record". I don't know if these settings files have comments, I inserted a mechanism to allow for standard # line comments, see below. Instead of printing it, you can write it to a file:
xml = open('Settings.xml','w');
xml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
xml.write('<hosts>\n');
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
xml.write(MakeXml(settings
xml.write('</hosts>');
xml.close()
def GetSettings(data):
lines = data.split('\n')
res = {}
for line in lines:
if line and (line[0]=='#'):
continue
tmp = line.split('=')
if(len(tmp)==2):
res[tmp[0]] = tmp[1]
return res
def MakeXml(settings):
return """ <host>
<name>%(name)s</name>
<ip>%(ip)s</ip>
<scan>%(scan)s</scan>
<config>%(config)s</config>
<enabled>%(enabled)s</enabled>
</host>\n""" % settings
ASKER
the settings file looks like the one attached. in the statement:
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
print MakeXml(settings)
what does filename refer to? is this the attirbute, ie name or ip or is the value?
settings.txt
for filename in files:
data = file(filename,'r').read()
settings = GetSettings(data)
print MakeXml(settings)
what does filename refer to? is this the attirbute, ie name or ip or is the value?
settings.txt
It is the file name including a relative path, fetched using glob.glob(). Run this code to see if you get the correct files:
import glob
files = glob.glob('Computers/*/set tings.conf ')
print files
You may need to adjust the path, depending on what is the current working directory when you run the script.
import glob
files = glob.glob('Computers/*/set
print files
You may need to adjust the path, depending on what is the current working directory when you run the script.
You may need to modify line 9 from my snippet above. Change this:
res[tmp[0]] = tmp[1]
...into this:
res[tmp[0].strip()] = tmp[1].strip()
This will remove unwanted spaces.
res[tmp[0]] = tmp[1]
...into this:
res[tmp[0].strip()] = tmp[1].strip()
This will remove unwanted spaces.
ASKER
i ran
import glob
files = glob.glob('Computers/*/set tings.conf ')
print files
and it printed all the fiels correctly, with a list like ['computer1\\settings.conf ', 'computer2\\settings.conf' , 'computer3\\settings.conf' ].
This is where i dont understand that for loop. What do i substitue for filename? Do i have to put a specific name - 'computer1\\settings.conf' , because that gives a syntax error. Or do i put something like '*/settings.conf'.
Sorry but i am failry new to python, still learning.
I also got an error, i will attach the code i ran and the error.
import glob
files = glob.glob('Computers/*/set
print files
and it printed all the fiels correctly, with a list like ['computer1\\settings.conf
This is where i dont understand that for loop. What do i substitue for filename? Do i have to put a specific name - 'computer1\\settings.conf'
Sorry but i am failry new to python, still learning.
I also got an error, i will attach the code i ran and the error.
import glob
files = glob.glob('*/settings.conf')
def GetSettings(data):
lines = data.split('\n')
res = ()
for line in lines:
if line and (line[0]=='#'):
continue
tmp = line.split('=')
if (len(temp)==2):
res[tmp[0].strip()] = tmp[1].strip()
return res
def MakeXML(settings):
return """ <host>
<name>%(name)s</name>
<ip>%(ip)s</ip>
<scan>%(scan)s</scan>
<config>%(config)s</config>
</host>\n""" %settings
for computer1 in files:
data = file(computer1, 'r').read()
settings = GetSettings(data)
print MakeXML(settings)
xml = open('settings.xml', 'w')
xml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
xml.write('<hosts>\n')
for computer1 in files:
data = file(computer1, 'r').read()
settings = GetSettings(data)
xml.write(MakeXML(settings))
xml.write('</hosts>')
xml.close(
error.txt
Line 11 should be:
if (len(tmp)==2):
"tmp", not "temp".
In python, when you have a list L, and iterate over it with a for loop like this:
for item in L:
print item
... the "item" variable is assigned each item in the list L, changing the value of "item" as it iterates trough the list.
The "filename" variable will contain the filename from the "files" list. In your code, you have called this "computer1", it is still just a variable name, and it will contain the names for each of the files, not just for computer1.
You can remove lines 23-26, this was just example code, outputting the XML to the screen. Lines 28-36 writes to the file.
if (len(tmp)==2):
"tmp", not "temp".
In python, when you have a list L, and iterate over it with a for loop like this:
for item in L:
print item
... the "item" variable is assigned each item in the list L, changing the value of "item" as it iterates trough the list.
The "filename" variable will contain the filename from the "files" list. In your code, you have called this "computer1", it is still just a variable name, and it will contain the names for each of the files, not just for computer1.
You can remove lines 23-26, this was just example code, outputting the XML to the screen. Lines 28-36 writes to the file.
ASKER
it is creating an xml file, but it is empty. I get the error:
in line 12, in GetSettings
res[tmp[0].strip()] = tmp[1].strip
TypeError: 'tuple' object does not support item assignment
in line 12, in GetSettings
res[tmp[0].strip()] = tmp[1].strip
TypeError: 'tuple' object does not support item assignment
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thats great, works like a charm. Cheers.