xmlのデータをcsv化して見やすくする
xmlデータはhtmlのようにツリー構造になっています。そのツリー構造からデータが格納されている部分を見つけます。データを見つけたら、人が読みやすい構造に変換します。一番読みやすいのはCSVファイルだとは思いますが、xmlデータにばらつきがあったりするとCSVで綺麗に読めるデータにはなりません。
今回はこんなことをやってみたよという報告です。CSV変換ももっといい方法があるかもしれません。
xmlデータをcsvに書き込むコード
#xmlデータの読み込み from xml.etree import ElementTree as ET import pprint tree = ET.parse('data-text.xml') root = tree.getroot() data = root.find('Data') all_data = [] for observation in data: record = {} for item in observation: lookup_key = list(item.attrib.keys())[0]#キーのリストの0番目を参照する。 if lookup_key == 'Numeric':#リストの0番目のkeyがNumericだったら rec_key = 'NUMERIC' rec_value = item.attrib['Numeric']#Numericの値を変数に格納 else:#リストの0番目がNumericではなかったら、lookupkeyの0番目をkeyに追加。 rec_key = item.attrib[lookup_key] rec_value = item.attrib['Code'] record[rec_key] = rec_value#辞書に値とキーを追加する キーはなかったら自動的に追加される all_data.append(record) pprint.pprint(all_data) #xml→csv書き込み print(all_data[0].values()) print(all_data[0].keys()) file= open('xml.csv', 'w', newline='') file_writer = csv.writer(file) file_writer.writerow(all_data[0].keys()) for i in range(len(all_data)): file_writer.writerow(all_data[i].values()) file.close()
プログラムコードの解説
非常に長ったらくpythonなのにいやったらしいコードです。全部説明するのは難ありなので、簡単に言いますとxmlデータから辞書データのリストにしています。ポイントは、
- ET.parse()でxmlファイルをパースする。
- getroot()でルートを取得します。ルートを取得するという言い方は非常にわかりにくいです。どのような形をしているのかもつかみづらいですが、先頭のタグ群が格納されると思うとわかりやすいかもしれません。
- root.find()でデータが格納されている部分を取得する
この一連の流れは非常にわかりにくいですが、ここで取得しているものはrootオブジェクトだと思っても差し支えないと思います。for observation in data:でforループしたら、dataの下層のルートがitemに格納されます。これは非常にわかりにくいと思います。
そしてitem.attribとすることでルートの属性(タグの属性)を辞書構造にすることができます。後の細かい動作は説明をはぶきますが、ポイントはルートを扱っているという認識をもつことです。
xmlをcsvに書き込むことはできるが難しい?
最終的にall_dataというリストは辞書を複数格納しているリストになっています。ですからリストのインデックスを指定して辞書にアクセスしvalues()やkeys()メソッドを呼び出せます。そしてこれらのメソッドは値をリストで返します。
csv.writerow()は引数にリストを与えるとそれを列と認識し書き込んでくれます。ですから、まずは辞書のキーをひっぱってきて列の項目を作ります。次に値をforで回してどんどん行を追加していきます。
xmlデータにばらつきがあるとcsvで見にくいデータになってしまう
これはxmlデータを見るとわかることですが、xmlデータは完全に整列されていないことがあります。ですからこの構文の手法ですと難があります。もっと他にいい方法があるとは思いますが、このコードは現実的ではないと思います。
コメント