我使用Python将CSV文件转换为XML格式。 CSV文件具有不同的行数,范围从2(包括标题)到无穷大。 (实际上10-15但除非有一些主要的性能问题,我想覆盖我的基础)为了转换文件,我有以下代码:
for row in csvData:
if rowNum == 0:
xmlData.write(' <'+csvFile[:-4]+'-1>' + "\n")
tags = row
# replace spaces w/ underscores in tag names
for i in range(len(tags)):
tags[i] = tags[i].replace(' ', '_')
if rowNum == 1:
for i in range(len(tags)):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
xmlData.write(' </'+csvFile[:-4]+'-1>' + "\n" + ' <' +csvFile[:-4]+'-2>' + "\n")
if rowNum == 2:
for i in range(len(tags)):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
xmlData.write(' </'+csvFile[:-4]+'-2>' + "\n")
if rowNum == 3:
for i in range(len(tags)):
xmlData.write('<'+csvFile[:-4]+'-3>' + "\n" + ' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
xmlData.write(' </'+csvFile[:-4]+'-3>' + "\n")
rowNum +=1
xmlData.write('</csv_data>' + "\n")
xmlData.close()
如您所见,如果行存在,我将手动创建上层标记。有没有更有效的方法来实现我创建<csvFile-*></csvFile-*>
标记的目标,而不是重复我的代码15次?谢谢!
答案 0 :(得分:4)
我会使用xml.etree.ElementTree或lxml.etree来编写XML。 xml.etree.ElementTree在标准库中,但没有内置的漂亮打印。 (您可以使用here中的缩进功能。)
lxml.etree是第三方模块,但它的tostring
方法内置了漂亮的打印功能。
使用lxml.etree,你可以这样做:
import lxml.etree as ET
csvData = [['foo bar', 'baz quux'],['bing bang', 'bim bop', 'bip burp'],]
csvFile = 'rowboat'
name = csvFile[:-4]
root = ET.Element('csv_data')
for num, tags in enumerate(csvData):
row = ET.SubElement(root, '{f}-{n}'.format(f = name, n = num))
for text in tags:
text = text.replace(' ', '_')
tag = ET.SubElement(row, text)
tag.text = text
print(ET.tostring(root, pretty_print = True))
产量
<csv_data>
<row-0>
<foo_bar>foo_bar</foo_bar>
<baz_quux>baz_quux</baz_quux>
</row-0>
<row-1>
<bing_bang>bing_bang</bing_bang>
<bim_bop>bim_bop</bim_bop>
<bip_burp>bip_burp</bip_burp>
</row-1>
</csv_data>
一些建议:
在Python中,几乎从不需要说
for i in range(len(tags)):
# do stuff with tags[i]
相反说
for tag in tags:
循环遍历tags
中的所有项目。
而不是通过
循环手动计算时间num = 0
for tags in csvData:
num += 1
而是使用enumerate函数:
for num, tags in enumerate(csvData):
像
这样的字符串' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n"
非常难以阅读。它混合了逻辑
缩进,使用标记的XML语法,使用end的minutia
行字符。这就是xml.etree.ElementTree
或lxml.etree
的位置
会帮助你。它将负责XML的序列化
您;您需要提供的只是XML元素之间的关系。
代码将更易读,更易于维护。