Python
 Computer >> コンピューター >  >> プログラミング >> Python

PythonでXMLを解析・編集・生成する方法|ElementTree APIの使い方を徹底解説

Pythonの標準ライブラリに含まれるXMLパーサーは、XMLファイルから必要な情報を読み取り、抽出するための最も手軽な手段のひとつです。このチュートリアルでは、xml.etree.ElementTree(ElementTree XML API)を使って、XMLファイルの「解析」「編集」「新規作成」を行う方法を、実際のコード例とともにわかりやすく解説します。

ElementTreeは、XMLデータの抽出・解析・変換をシンプルに実現できるAPIであり、外部ライブラリをインストールすることなくすぐに使い始められるのが大きな魅力です。

それでは、さっそくElementTreeを使ったPythonのXML処理を見ていきましょう。

例1:XMLファイルを作成する

ルート要素と子要素を持つXMLファイルの生成

まずは、1つの要素とその子要素を持つ新しいXMLファイルを作成してみます。

# 必要なライブラリをインポート
import xml.etree.ElementTree as xml

def createXML(filename):
    # ルート要素から開始
    root = xml.Element("users")
    children1 = xml.Element("user")
    root.append(children1)

    tree = xml.ElementTree(root)
    with open(filename, "wb") as fh:
        tree.write(fh)

if __name__ == "__main__":
    createXML("testXML.xml")

上記のプログラムを実行すると、カレントワーキングディレクトリに「testXML.xml」という名前の新しいファイルが作成されます。

ファイルの中身は次のようになっています。

<users><user /></users>

ここで注目すべきポイントは、ファイルを書き込む際に 「wb」(バイナリモード) を指定している点です。ElementTreeのwriteメソッドはバイト列を出力するため、テキストモードではなくバイナリモードで開くのが基本となります。

XML要素に値を追加する

次に、先ほどのプログラムにSubElementを使って要素を追加し、それぞれに値を設定してみましょう。

# 必要なライブラリをインポート
import xml.etree.ElementTree as xml

def createXML(filename):
    # ルート要素から開始
    root = xml.Element("users")
    children1 = xml.Element("user")
    root.append(children1)

    userId1 = xml.SubElement(children1, "Id")
    userId1.text = "hello"

    userName1 = xml.SubElement(children1, "Name")
    userName1.text = "Rajesh"

    tree = xml.ElementTree(root)
    with open(filename, "wb") as fh:
        tree.write(fh)

if __name__ == "__main__":
    createXML("testXML.xml")

プログラムを実行すると、値を持つ新しい要素が追加されていることが確認できます。

<users>
    <user>
        <Id>hello</Id>
        <Name>Rajesh</Name>
    </user>
</users>

このように、xml.SubElement(親要素, "タグ名") で子要素を作成し、.text プロパティに文字列を代入するだけで、簡単にXMLの構造を組み立てられます。

既存のXMLデータを編集する

今度は、ファイルからXMLデータを読み込み、内容を更新する方法を見ていきます。以下のようなXMLファイルを用意しました。

newdata.xml

<users>
    <user>
        <id>1a</id>
        <name>Rajesh</name>
        <salary>NA</salary>
    </user>
    <user>
        <id>2b</id>
        <name>TutorialsPoint</name>
        <salary>NA</salary>
    </user>
    <user>
        <id>3c</id>
        <name>Others</name>
        <salary>NA</salary>
    </user>
</users>

このXMLファイル内の全ユーザーの給与(salary)を一括で更新してみましょう。

# 必要なライブラリをインポート
import xml.etree.ElementTree as ET

def updateET(filename):
    # ルート要素を取得
    tree = ET.ElementTree(file=filename)
    root = tree.getroot()

    # salaryタグをすべて走査して値を更新
    for salary in root.iter('salary'):
        salary.text = '500000'

    tree = ET.ElementTree(root)
    with open("newdata.xml", "wb") as fh:
        tree.write(fh)

if __name__ == "__main__":
    updateET("newdata.xml")

実行結果

実行後のファイルを確認すると、すべてのsalaryが「NA」から「500000」に変更されています。

ポイントは root.iter('salary') です。iterメソッドを使うことで、ツリー全体から指定したタグ名の要素だけを効率よく走査でき、条件に合致する要素のtext属性を書き換えるだけで一括更新が完了します。

例2:Python XMLパーサーでデータを読み取る

続いて、ファイル内のXMLデータを解析(パース)し、その内容をコンソールに出力するプログラムを書いてみます。

# 必要なライブラリをインポート
import xml.etree.cElementTree as ET

def parseXML(file_name):
    # ElementTreeでXMLを解析
    tree = ET.ElementTree(file=file_name)
    print(tree.getroot())
    root = tree.getroot()
    print("tag=%s, attrib=%s" % (root.tag, root.attrib))

    # 子要素から情報を取得
    print("-" * 25)
    print("Iterating using getchildren()")
    print("-" * 25)
    users = root.getchildren()
    for user in users:
        user_children = user.getchildren()
        for user_child in user_children:
            print("%s=%s" % (user_child.tag, user_child.text))

if __name__ == "__main__":
    parseXML("newdata.xml")

出力結果

<Element 'users' at 0x0551A5A0>
tag = users, attrib = {}
-------------------------
Iterating using getchildren()
-------------------------
id = 1a
name = Rajesh
salary = 500000
id = 2b
name = TutorialsPoint
salary = 500000
id = 3c
name = Others
salary = 500000

root.tag でルート要素のタグ名、root.attrib で属性情報を取得できることがわかります。さらに子要素を順番にたどることで、各ユーザーのid・name・salaryの値をすべて取り出せています。

補足:最新のPythonでの注意点

なお、上記コードで使われている getchildren() メソッドと xml.etree.cElementTree モジュールは、Python 3.9以降で非推奨(削除済み)となっています。最新の環境では、以下のように書き換えることをおすすめします。

  • import xml.etree.cElementTree as ETimport xml.etree.ElementTree as ET
  • root.getchildren()list(root)

これらの置き換えを行えば、Python 3の最新バージョンでも同じように動作します。

まとめ

ElementTreeを使えば、XMLファイルの作成・値の追加・既存データの編集・解析がすべてPython標準ライブラリだけで完結します。設定ファイルやAPIレスポンスなど、XMLを扱う場面は依然として多いため、本記事のコード例を参考に、ぜひ実際のプロジェクトでも活用してみてください。

  1. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが

  2. Pythonで辞書からXMLを生成する方法を徹底解説

    Pythonの辞書(dict)オブジェクトからXMLを生成したい場合、dicttoxml パッケージを利用するのが最も手軽な方法です。このライブラリを使えば、複雑な入れ子構造を持つ辞書でも、数行のコードで自動的にXML形式へ変換できます。 dicttoxmlパッケージのインストール まずはpipコマンドでdicttoxmlをインストールしましょう。ターミナルまたはコマンドプロンプトで以下を実行します。 $ pip install dicttoxml インストールが完了したら、すぐにdicttoxmlメソッドを使ってXMLを生成できます。 基本的な使い方:辞書をXMLに変換する 以下の例では、ネ