Help us understand the problem. What is going on with this article?

PythonでのXMLファイル操作例

はじめに

今回は今研究で扱っているxml形式のデータをPythonでどう扱うのかをまとめてみました。
Qiitaに記事を出す練習も兼ねているので、わかりずらいかもしれません。悪しからず...
基本的には、公式チュートリアルを参照しています。
(https://docs.python.org/ja/3/library/xml.etree.elementtree.html)

環境

OS: macOS Mojave
pythonのバージョン :3.7.2

xmlとは

簡単に言えば、複雑な情報をみやすくするための言語です。
xmlの構造の一例を以下に示します。
(引用元:pythonのElementTree XML APIのサイトhttps://docs.python.org/ja/3/library/xml.etree.elementtree.html)

country.xml
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

それぞれ詳しくみていきます。
XMLでは各情報(contents)を要素名(element)を記載したタグで括ります。

<element>contents</element>

また、要素名が同一の場合は、各要素に対して属性(attribute)と属性値(attribute value)をつけることがあります。

<element attribute="attribute value">contents</element>

pythonでxmlを扱う一例

ここでは、上のcountry.xmlをファイルとして扱うと仮定して、xml解析方法を説明します。
まずxmlを扱うためのライブラリをimportしましょう。

import xml.etree.ElementTree as ET

次に、xmlファイルを以下のコードで読み込みます。

#xmlデータを読み込みます
tree = ET.parse('country.xml')
#一番上の階層の要素を取り出します
root = tree.getroot()

rootには読み込んだxmlの最上階層にあるの情報を保持しています。
rootの要素名と属性をみたい場合は次のコードでみれます。

print(root.tag)
print(root.attrib)
実行結果
data
{}

rootの要素名がdataと出てきました。属性はないので、ないも出てきてないです。

次に、rootより下の階層は以下のようにfor文を使って抽出できます。

for child in root:
    print(child.tag)
    print(child.attrib)
実行結果
country
{'name': 'Liechtenstein'}
country
{'name': 'Singapore'}
country
{'name': 'Panama'}

dataの下にある3つの国の情報が出てきましたね。属性と属性値は辞書型として抽出することができます。とても便利...
辞書型なので、以下のようにして、国名の情報を抽出することができます。

for child in root:
    print(child.attrib["name"])
実行結果
Liechtenstein
Singapore
Panama

childをもう一度for文に入れれば、さらに下の階層の情報を見ることができます。しかし、一つ下の階層の情報を見るならば、findを使った方がやりやすいです。例えば、各国のrank情報を抽出したい場合は以下のようにします。

for child in root:
    print(child.attrib["name"],child.find("rank").text)
実行結果
Liechtenstein 1
Singapore 4
Panama 68

findで指定した要素の下の階層の要素を指定することができます。今回はの下にあるを指定しました。<></>で括られている情報を文字列として、抽出するには.textと書けば、抽出することができます。

まとめ

初めて、本格的な記事を書きましたが、文章に落とし込む難しさを実感しました。同時に、今まで参照してきた技術記事がどれだけ凄いのかを改めて実感しました。今後も自分のスキルアップのために、頑張りたいと思います...! もし改善点があれば、気軽にコメントください。

sino20023
某日系企業でデータサイエンティストやってます。大学時代はバイオインフォマティクスの研究をしていました。よろしくお願いします。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away