Skip to main content
 首页 » 编程设计

python之在 python 中使用 argparse 将 csv 转换为 xml

2025年05月04日13TianFang

一个非常快速的问题,基本上我的程序接受一个输入文件,它是一个 csv 文件,然后将它转换成一个 xml 文件。但是,xml 文件的名称可以由用户输入设置,或者如果用户未指定名称,则 xml 文件将与 csv 文件同名,但扩展名为 .xml。我需要后者的帮助。到目前为止,我的程序在为输出文件指定名称时工作,但我不知道如何在用户未输入名称时设置 xml 文件名。我知道,如果用户没有设置名称,那么 argparse.outputfile 就是 none,我可以编写一个简单的 if 语句来检查,但我不知道如何将名称设置为与之后的 csv 文件名相同。这是我的代码:

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”添加到文件顶部的导入列表中。然后,在解析之后,您可以检查并设置参数:

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

顺便说一句,参数默认为其长选项名称。当你想使用不同的名称时,你只需要'dest'关键字。因此,例如,“详细”可能是:

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

编辑:这里是使用输出文件处理和 chepner 的建议对文件名使用位置参数进行修改的示例。

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