1

我正在使用 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 次以上?谢谢!

4

1 回答 1

4

我会使用xml.etree.ElementTreelxml.etree来编写 XML。xml.etree.ElementTree 在标准库中,但没有内置的漂亮打印。(但是,您可以从这里使用 indent 函数)。

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
    

    而是使用枚举函数:

    for num, tags in enumerate(csvData):
    
  • 像这样的字符串

    '        ' + '<' + tags[i] + '>' \
                             + row[i] + '</' + tags[i] + '>' + "\n"
    

    非常难以阅读。它将缩进逻辑、标签的 XML 语法以及行尾字符的细节混合在一起。这就是xml.etree.ElementTreelxml.etree 会帮助你的地方。它将为您处理 XML 的序列化;您需要提供的只是 XML 元素之间的关系。代码将更具可读性和更易于维护。

于 2012-10-25T16:38:06.287 回答