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.ElementTreeまたはlxml.etreeを使用して XML を記述します。xml.etree.ElementTree は標準ライブラリにありますが、プリティ プリンティングが組み込まれていません。(ただし、ここからインデント機能を使用できます)。

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.etreeXML のシリアル化を処理します。提供する必要があるのは、XML 要素間の関係だけです。コードははるかに読みやすく、保守が容易になります。

于 2012-10-25T16:38:06.287 に答える