1

I have to use the command prompt and python to recieve an input in the form of a csv file, then read it and convert it into a xml file with the same name as the csv file except with .xml file extension or the user can set the ouput file name and path using the -o --output optional command line argument. Well i have searched on google for days, and so far my program allows me to input command line arguments and i can convert the csv to an xml file but it doesn't print it using the same name as the csv file or when the user sets the name. Instead it just prints out a blank file. Here is my code:

    import sys, argparse
    import csv
    import indent
    from xml.etree.ElementTree import ElementTree, Element, SubElement, Comment, tostring

    parser=argparse.ArgumentParser(description='Convert wordlist text files to various formats.', prog='Text Converter')
    parser.add_argument('-v','--verbose',action='store_true',dest='verbose',help='Increases messages being printed to stdout')
    parser.add_argument('-c','--csv',action='store_true',dest='readcsv',help='Reads CSV file and converts to XML file with same name')
    parser.add_argument('-x','--xml',action='store_true',dest='toxml',help='Convert CSV to XML with different name')
    parser.add_argument('-i','--inputfile',type=argparse.FileType('r'),dest='inputfile',help='Name of file to be imported',required=True)
    parser.add_argument('-o','--outputfile',type=argparse.FileType('w'),dest='outputfile',help='Output file name')
    args = parser.parse_args()

    def main(argv):
        reader = read_csv()
        if args.verbose: 
            print ('Verbose Selected')
        if args.toxml:
            if args.verbose:
               print ('Convert to XML Selected')
            generate_xml(reader)
        if args.readcsv:
            if args.verbose:
                print ('Reading CSV file')
            read_csv()
        if not (args.toxml or args.readcsv):
            parser.error('No action requested')
        return 1

    def read_csv():
        with open ('1250_12.csv', 'r') as data:
            return list(csv.reader(data))

    def generate_xml(reader):
        root = Element('Solution')
        root.set('version','1.0')
        tree = ElementTree(root)

        head = SubElement(root, 'DrillHoles')
        head.set('total_holes', '238')

        description = SubElement(head,'description')
        current_group = None
        i = 0
        for row in reader:
            if i > 0:
                x1,y1,z1,x2,y2,z2,cost = row
                if current_group is None or i != current_group.text:
                    current_group = SubElement(description, 'hole',{'hole_id':"%s"%i})

                    collar = SubElement (current_group, 'collar',{'':', '.join((x1,y1,z1))}),
                    toe = SubElement (current_group, 'toe',{'':', '.join((x2,y2,z2))})                                       
                    cost = SubElement(current_group, 'cost',{'':cost})
            i+=1    
        indent.indent(root)
        tree.write(open('hole.xml','w'))
    if (__name__ == "__main__"):

sys.exit(main(sys.argv))

for the generate_xml() function, you can ignore it since it accepts csv files formatted a certain way so you might not understand it but, i think the problem lies in tree.write() since that part generates the xml file with a name that is written in the code itself and not the arguments at the command prompt.

4
  • What is your problem: Write XML or write to a file with a given path/name? It's not clear from your question. Commented Jun 10, 2013 at 15:26
  • I am unable to convert the csv file to an xml file with the same as the csv file except with the .xml extension and i cannot convert the csv file to an xml file with a user setting the name of the new xml file. Commented Jun 10, 2013 at 15:28
  • That part converts the csv file to the xml file but the name 'hole.xml' is written inside the code which is not what i want. I need some way to get the name using the command prompt and set it as the name of the xml file that is to be generated using data obtained from reading the csv file Commented Jun 10, 2013 at 15:31
  • @Andy you can accept an answer by clicking on the check mark beside it :) Commented Jun 10, 2013 at 22:31

2 Answers 2

1

You need to pass a file argument to generate_xml(). You appear to have the output file in args.outputfile.

generate_xml(reader, args.outputfile)

...
def generate_xml(reader, outfile):
    ...
    tree.write(outfile)

You should probably also make use of args.inputfile:

reader = read_csv(args.inputfile)
...
def read_csv(inputfile):
    return list(csv.reader(inputfile))

And this line does not do anything useful, it processes the .csv file, but doesn't do anything with the results:

read_csv()
Sign up to request clarification or add additional context in comments.

7 Comments

thanks for the help, but after i run it on command prompt, there is an error : coercing to unicode: need string or buffer, file found
right, I see now that args.inputfile and args.outputfile are already File type objects. I will update my answer.
how are you calling your script?
argparse.py -i 1250_12.csv -x where argparse.py is the name and i- is the input function and 1250_12.csv is the csv file name and -x is to convert the csv to xml
OK, you need to add a -o output.xml.
|
1

The following code has been adapted from FB36's recipie on code.activestate.com

It will do what you need and you don't have to worry about the headers in the csv file, though there should only be one header (the first row) in the csv file. Have a look at the bottom of this page if you want to do batch conversion.

'''Convert csv to xml file

csv2xml.py takes two arguments:  
 1. csvFile: name of the csv file (may need to specify path to file)
 2. xmlFile: name of the desired xml file (path to destination can be specified)

If only the csv file is provided, its name is used for the xml file. 

Command line usage: 
 example1: python csv2xml.py 'fileName.csv' 'desiredName.xml'
 example2: python csv2xml.py '/Documents/fileName.csv' '/NewFolder/desiredName.xml'
 example3: python csv2xml.py 'fileName.csv'

This code has been adapted from: http://code.activestate.com/recipes/577423/
'''

import csv

def converter(csvFile, xmlFile):
    csvData = csv.reader(open(csvFile))

    xmlData = open(xmlFile, 'w')
    xmlData.write('<?xml version="1.0"?>' + "\n")

    # there must be only one top-level tag
    xmlData.write('<csv_data>' + "\n")

    rowNum = 0
    for row in csvData:
        if rowNum == 0:
            tags = row
            # replace spaces w/ underscores in tag names
            for i in range(len(tags)):
                tags[i] = tags[i].replace(' ', '_')
        else: 
            xmlData.write('<row>' + "\n")
            for i in range(len(tags)):
                xmlData.write('    ' + '<' + tags[i] + '>' \
                              + row[i] + '</' + tags[i] + '>' + "\n")
            xmlData.write('</row>' + "\n")

        rowNum +=1

    xmlData.write('</csv_data>' + "\n")
    xmlData.close()

## for using csv2xml.py from the command line
if __name__ == '__main__':
    import sys

    if len(sys.argv)==2:
        import os
        csvFile = sys.argv[1]
        xmlFile = os.path.splitext(csvFile)[0] + '.xml'
        converter(csvFile,xmlFile)
    elif len(sys.argv)==3:
        csvFile = sys.argv[1]
        xmlFile = sys.argv[2]   
        converter(csvFile,xmlFile)
    else:
        print __doc__

Comments

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.