2013-06-10 3 views
1

Мне нужно использовать командную строку и python для получения ввода в виде файла csv, затем прочитать его и преобразовать в файл xml с тем же именем, что и файл csv за исключением расширения файла .xml, или пользователь может установить имя и путь файла вывода, используя аргумент командной строки -o --output. Ну, я искал в google в течение нескольких дней, и до сих пор моя программа позволяет мне вводить аргументы командной строки, и я могу преобразовать csv в xml-файл, но он не печатает его с тем же именем, что и файл csv, или когда пользователь устанавливает имя. Вместо этого он просто распечатывает пустой файл. Вот мой код:Использование Argparse для создания конвертера файлов в Python

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)) 

для функции generate_xml(), вы можете игнорировать его, поскольку он принимает CSV-файлы отформатированы определенным образом, чтобы вы не могли бы понять это, но, я думаю, что проблема заключается в tree.write (), так как эта часть генерирует XML-файл с именем, которое написано в самом коде, а не в аргументах командной строки.

+0

В чем ваша проблема: Напишите XML или напишите файл с заданным путем/именем? Это не ясно из вашего вопроса. – Ber

+0

Я не могу преобразовать файл csv в xml-файл с тем же, что и файл csv, за исключением расширения .xml, и я не могу преобразовать файл csv в xml-файл с пользователем, определяющим имя нового xml-файла. – Andy

+0

Эта часть преобразует файл csv в xml-файл, но имя «hole.xml» написано внутри кода, который не является тем, что я хочу. Мне нужно каким-то образом получить имя с помощью командной строки и установить его как имя файла xml, который должен быть сгенерирован с использованием данных, полученных при чтении файла csv. – Andy

ответ

1

Вам необходимо передать аргумент файла generate_xml(). У вас есть выходной файл в файле args.outputfile.

generate_xml(reader, args.outputfile) 

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

Вы, вероятно, следует также использовать args.inputfile:

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

И эта линия не делает ничего полезного, она обрабатывает файл .csv, но ничего не делать с результатами:

read_csv() 
+0

спасибо за помощь, но после того, как я запустил ее в командной строке, появилась ошибка: принуждение к unicode: нужна строка или буфер, найденный файл – Andy

+0

правильно, теперь я вижу, что args.inputfile и args.outputfile уже Объекты типа «Файл». Я уточню свой ответ. –

+0

его по-прежнему та же ошибка, но теперь он говорит, что нетто-тип найден – Andy

1

Следующий код был адаптирован из recipie FB36 «S на code.activestate.com

Он будет делать то, что вам нужно, и вам не нужно беспокоиться о заголовках в файле csv, хотя в файле csv должен быть только один заголовок (первая строка). Посмотрите на дно this page, если вы хотите сделать пакетное преобразование.

'''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__ 
Смежные вопросы