Domanda

I need to generate xml files poulated with data from a csv file in python

I have two input files:

one CSV file named data.csv containing data like this:

ID  YEAR    PASS    LOGIN   HEX_LOGIN
14Z 2013    (3e?k<.P@H}l    hex0914Z    F303935303031345A
14Z 2014    EAeW+ZM..--r    hex0914Z    F303935303031345A
.......

One Template file named template.xml

<?xml version="1.0"?>
<SecurityProfile xmlns="security_profile_v1">
<year></year>
<security>
<ID></ID>
<login></login>
<hex_login></hex_login>
<pass></pass>
</security>
</SecurityProfile>

I want to get as many output files as lines in the csv data file, each output filed named YEAR_ID, with the data from the csv file in the xml fields:

Output files contentes:

Content of output file #1 named 2013_0950014z:

<?xml version="1.0"?>
<SecurityProfile xmlns="security_profile_v1">
<year>2013</year>
<security>
<ID>14Z</ID>
<login>hex0914</login>
<hex_login>F303935303031345A</hex_login>
<pass>(3e?k<.P@H}l</pass>
</security>
</SecurityProfile>

Content of output file #2 named 2014_0950014z:

<?xml version="1.0"?>
<SecurityProfile xmlns="security_profile_v1">
<year>2014</year>
<security>
<ID>14Z</ID>
<login>hex0914</login>
<hex_login>F303935303031345A</hex_login>
<pass>EAeW+ZM..--r</pass>
</security>
</SecurityProfile>

Thank you for your suggestions.

È stato utile?

Soluzione

Can you make changes the template? If so, I would do the following to make this a bit simpler:

<?xml version="1.0"?>
<SecurityProfile xmlns="security_profile_v1">
<year>{year}</year>
<security>
<ID>{id}</ID>
<login>{login}</login>
<hex_login>{hex_login}</hex_login>
<pass>{pass}</pass>
</security>
</SecurityProfile>

Then, something like this would work:

import csv

input_file_name = "some_file.csv" #name/path of your csv file
template_file_name = "some_file.xml" #name/path of your xml template
output_file_name = "{}_09500{}.xml"

with open(template_file_name,"r") as template_file:
    template = template_file.read()

with open(input_file_name,"r") as csv_file:
    my_reader = csv.DictReader(csv_file)
    for row in my_reader:
        with open(output_file_name.format(row["YEAR"],row["ID"]),"w") as current_out:
            current_out.write(template.format(year=row["YEAR"],
                                              id=row["ID"],
                                              login=row["LOGIN"],
                                              hex_login=row["HEX_LOGIN"],
                                              pass=row["PASS"]))

If you can't modify the template, or want to process it as XML instead of basic string manipulation, then it's a bit more involved.

EDIT:

Modified answer to use csv.DictReader rather than csv.reader.

Fixed variable names opening input CSV file and writing the output. Removed 'binary' mode file operations.

Altri suggerimenti

import csv
from collections import defaultdict

header = '<?xml version="1.0"?><SecurityProfile xmlns="security_profile_v1">\n'
footer = '\n</SecurityProfile>'
entry = '''<security>
              <ID>{0[ID]}</ID>
              <login>{0[LOGIN]}</login>
              <hex_login>{0[HEX_LOGIN]}</hex_login>
              <pass>{0[PASS]}</pass>
           </security>'''

rows = defaultdict(list)

with open('infile.csv') as f:
   reader = csv.DictReader(f, delimiter='\t')
   for item in reader:
      rows[reader['YEAR']].append(item)

for year,data in rows.iteritems():
   with open('{}.xml'.format(year), 'w') as f:
      f.write(header)
      f.write('<year>{}</year>\n'.format(year))
      for record in data:
          f.write(entry.format(record))
          f.write('\n')
      f.write(footer)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top