在python中使用argparse将csv转换为xml [英] Using argparse to convert csv to xml in python

查看:341
本文介绍了在python中使用argparse将csv转换为xml的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个真正快速的问题,基本上我的程序采用一个输入文件,它是一个csv文件,然后将其转换为一个xml文件。但是,xml文件的名称可以由用户输入设置,或者如果用户没有指定名称,则xml文件将具有与csv文件相同的名称,除了.xml扩展名。我需要帮助后者。到目前为止,我的程序工作时,输出文件给一个名称,但我不知道如何设置xml文件名时,用户不输入名称。我知道,如果用户没有设置名称,然后argparse.outputfile是无,我可以写一个简单的if语句检查,但我不知道如何设置名称与csv文件名相同。这是我的代码:

A really quick quesiton, basically my program takes an inputfile which is a csv file and then converts it into a xml file. However, the name of the xml file can either be set by the user input or if the user doesn't specify the name, then the xml file will have the same name as the csv file except with a .xml extension. I need help with the latter. So far my program works when the output file is given a name but i don't know how to set the xml file name when the user doesn't input a name. I know that if the user doesn't set a name then argparse.outputfile is none and i can write a simple if statement to check but i do not know how to set the name to be the same as the csv file name after. 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(args.inputfile)
    if args.verbose: 
        print ('Verbose Selected')
    if args.toxml:
        if args.verbose:
            print ('Convert to XML Selected')
        generate_xml(reader, args.outputfile)
    if args.readcsv:
        if args.verbose:
            print ('Reading CSV file')
    if not (args.toxml or args.readcsv):
        parser.error('No action requested')
    return 1

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

def generate_xml(reader,outfile):
    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(outfile)

if (__name__ == "__main__"):
    sys.exit(main(sys.argv))


推荐答案

将import os添加到文件顶部的导入列表中。然后,在解析后,您可以检查并设置参数:

Add "import os" to the list of imports at the top of the file. Then, right after parsing, you can check and set the argument:

if args.outputfile is None:
    args.outputfile = os.path.splitext(args.inputfile)[0] + '.xml'

顺便说一句,参数默认为它们的长选项名称。当您想使用不同的名称时,只需要'dest'关键字。例如,'verbose'可以是:

By the way, arguments default to their long option name. You only need the 'dest' keyword when you want to use a different name. So, for example, 'verbose' could be:

parser.add_argument('-v', '--verbose', action='store_true',
    help='Increases messages being printed to stdout')

编辑:这里是输出文件处理和使用位置参数为文件名使用chepner的建议重做的示例。

Here is the example reworked with outputfile handling and with chepner's suggestion to use positional arguments for the file names.

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

def get_args(args):
    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=str,help='Name of file to be imported',required=True)
    #parser.add_argument('-o','--outputfile',help='Output file name')
    parser.add_argument('inputfile',type=str,help='Name of file to be imported')
    parser.add_argument('outputfile',help='(optional) Output file name',nargs='?')
    args = parser.parse_args()
    if not (args.toxml or args.readcsv):
        parser.error('No action requested')
        return None
    if args.outputfile is None:
        args.outputfile = os.path.splitext(args.inputfile)[0] + '.xml'
    return args

def main(argv):
    args = get_args(argv[1:])
    if args is None:
        return 1
    inputfile = open(args.inputfile, 'r')
    outputfile = open(args.outputfile, 'w')
    reader = read_csv(inputfile)
    if args.verbose:
        print ('Verbose Selected')
    if args.toxml:
        if args.verbose:
            print ('Convert to XML Selected')
        generate_xml(reader, outputfile)
    if args.readcsv:
        if args.verbose:
            print ('Reading CSV file')
    return 1 # you probably want to return 0 on success

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

def generate_xml(reader,outfile):
    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(outfile)

if (__name__ == "__main__"):
    sys.exit(main(sys.argv))

这篇关于在python中使用argparse将csv转换为xml的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆