【明快】PythonでXMLを扱う基本を徹底解説|実コード付

※本サイトにはプロモーション・広告が含まれています。

(最終更新日:2023年7月)

✔このような方へ向けて書かれた記事となります

「PythonでXMLをどう扱ったらいいかわからない」と悩む方
「PythonでXMLを操作する方法を知りたい」
「PythonでXML操作の実例が見てみたい」

✔当記事を通じてお伝えすること

  • Pythonを用いたXMLの基本的な取り扱い方法
  • PythonでXMLを操作する詳しい手順とその応用例
  • PythonでXMLを操作する具体的な例示

当記事では、PythonでXMLを操作する基本知識から応用例まで、さまざまな観点から詳しく解説します。

具体的なコード例を交えながら、Pythonを用いたXMLの活用方法を掘り下げていきます。

ぜひ最後までご覧ください。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロジェクトマネージャー/SE(元外資系金融機関営業)

【副業】ブログ(月間15万PV)/YouTube/Web・アプリ制作

コミュニケーション × ビジネススキル × 文章力 × プログラミングスキルを活かし、30後半からのIT系職へシフト。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

PythonでXMLを扱うための前提知識

こちらでは、PythonとXMLの関連性についてお伝えしていきます。

  • XMLとは?
  • PythonとXMLの関連性

XMLとは?

XML(Extensible Markup Language)とは、データを保存したり、インターネット上で送受信したりするために広く使われているマークアップ言語です。

SGML (Standard Generalized Markup Language) のサブセットとして設計され、タグを使用してデータの各部分をラベル付けします。

ユニバーサルな形式を提供することで、データ構造を人間と機械の両方が理解できるのです。

<book>
  <title>Harry Potter and the Sorcerer's Stone</title>
  <author>J.K. Rowling</author>
  <year>1997</year>
</book>

ただしXML自体は、データをどのように扱うべきかや、それが何を意味するのかについては何も教えてくれません。

各アプリケーションがどのように扱うかは、そのアプリケーション次第なのです。

PythonとXMLの関連性

PythonとXMLの関連性は、主にデータの解析と操作に関わるものです。

Pythonはその豊富なライブラリと簡易な構文のおかげで、さまざまなデータ形式を扱うのに非常に適しています。

その中にはXMLも含まれており、PythonはXMLデータを解析し、操作するための機能を提供しています。

例えばPythonには、xml.etree.ElementTreexml.dom.minidomなどの組み込みライブラリが存在します。

これらにより、XMLデータを解析したり、新たにXMLデータを生成したりが可能です。

import xml.etree.ElementTree as ET

xml_data = """
<root>
    <element1 attribute="value1">Text1</element1>
    <element2 attribute="value2">Text2</element2>
    <element3 attribute="value3">Text3</element3>
</root>
"""

root = ET.fromstring(xml_data)

for elem in root:
    print(f"要素: {elem.tag}, 属性: {elem.attrib}, テキスト: {elem.text}")

"""出力結果
要素: element1, 属性: {'attribute': 'value1'}, テキスト: Text1
要素: element2, 属性: {'attribute': 'value2'}, テキスト: Text2
要素: element3, 属性: {'attribute': 'value3'}, テキスト: Text3
"""

またXMLは、Web APIから返されるデータの形式として頻繁に使用されています。

このため、Pythonを使ってこれらのAPIを利用する場合、XMLデータをパース(解析)して内容を抽出し、必要に応じてデータを操作できなければなりません。

import xml.etree.ElementTree as ET

# APIから返されたXMLデータ(仮のデータ)
xml_data = '''
<response>
  <status>200</status>
  <message>成功</message>
  <data>
    <user>
      <name>アリス</name>
      <age>25</age>
    </user>
    <user>
      <name>ボブ</name>
      <age>30</age>
    </user>
  </data>
</response>
'''

# XMLデータをパースしてElementTreeオブジェクトを作成
root = ET.fromstring(xml_data)

# 必要な要素の値を取得して表示
status = root.find('status').text
message = root.find('message').text
users = root.findall('data/user')

print(f"ステータス: {status}")
print(f"メッセージ: {message}")
print("ユーザー:")
for user in users:
    name = user.find('name').text
    age = user.find('age').text
    print(f"  名前: {name}, 年齢: {age}")

""" 出力結果
ステータス: 200
メッセージ: 成功
ユーザー:
  名前: アリス, 年齢: 25
  名前: ボブ, 年齢: 30
"""

PythonとXMLを組み合わせることで、Webサービスからのデータ収集や、設定ファイルの生成・解析、また大量の文書データの扱いなど、多岐に渡るタスクを効率的におこなえるのです。

XMLの基本

こちらでは、XMLの基本構造と要素についてお伝えしていきます。

  • XMLの木構造と要素
  • サンプルXMLの紹介

XMLの木構造と要素

XMLの構造は、タグと要素で構成される木構造です。

ルート要素が一番上にあり、その下に子要素が配置されます。

各要素は開始タグと終了タグで囲まれ、属性やテキストを含めるのです。

この構造は、情報を階層的かつ整理された形で表現するのに適しています。

サンプルXMLの紹介

以下は、XMLのサンプルです。

<persons>
    <person name="John Doe" age="30">
        <address city="New York" zip="10001"/>
    </person>
    <person name="Jane Doe" age="28">
        <address city="Los Angeles" zip="90001"/>
    </person>
</persons>

このXMLでは、personsがルート要素で、その下に複数のperson要素があります。

person要素はnameage属性を持ち、さらに子要素としてaddressを持つのが読み取れるでしょう。

PythonでXMLを解析する

こちらでは、PythonでXMLを解析する方法について詳しくお伝えします。

  • XMLの解析入門
  • XMLファイルの解析
  • XMLデータの直接解析
  • プルAPIを利用した非ブロックパース

XMLの解析入門

PythonでXMLを解析するには、xmlモジュールを使用します。

これはPythonの標準ライブラリに含まれているため、追加のインストールは不要です。

xmlモジュールにはElementTreeというサブモジュールが含まれており、これを使用してXMLの解析をおこないます。

ElementTreeは、XMLデータを木構造として扱い、要素の抽出や操作が可能です。

XMLファイルの解析

XMLファイルからデータを読み込む場合、ElementTreeparse関数を使用します。

これにより、XMLファイルを木構造として解析し、要素にアクセスできるのです。

import xml.etree.ElementTree as ET

tree = ET.parse('sample.xml')
root = tree.getroot()

for person in root.findall('person'):
    name = person.getattribute('name')
    age = person.getattribute('age')
    print(name, age)

上記のコードは、sample.xmlというXMLファイルを解析し、person要素のnameおよびage属性を出力します。

XMLデータの直接解析

XMLデータが文字列として与えられた場合、ElementTreefromstring関数を使用して解析します。

import xml.etree.ElementTree as ET

xml_data = """<persons>
    <person name="John Doe" age="30">
        <address city="New York" zip="10001"/>
    </person>
</persons>"""

root = ET.fromstring(xml_data)

for person in root.findall('person'):
    name = person.get('name')
    age = person.get('age')
    print(name, age)

プルAPIを利用した非ブロックパース

大きなXMLファイルを効率的に解析するために、プル型パーサーを利用できます。

これには、xml.etree.ElementTreeのiterparse関数を利用しましょう。

XMLファイル全体をメモリにロードするのではなく、要素を逐次処理してメモリ使用量を抑えています。

import xml.etree.ElementTree as ET

for event, elem in ET.iterparse('large_file.xml', events=('start', 'end')):
    if event == 'start':
        if elem.tag == 'person':
            # 処理
    elem.clear()  # メモリの解放

XMLファイルの操作方法

こちらでは、XMLファイルの操作方法を見ていきます。

XMLファイルを扱うのであれば、必須のスキルです。

  • PythonでのXML文書の構築方法
  • XML要素の検索手法
  • XMLファイルの編集と書き換え
  • 名前空間付きXMLの解析スキル

PythonでのXML文書の構築方法

Pythonでは、ElementTreeモジュールを使用して新しいXML文書を作成できます。

手順はこちらです。

  • Elementオブジェクトを作成する
  • それを文書のルート要素とする
  • SubElement関数を使用して、子要素を追加する

例を見てみましょう。

import xml.etree.ElementTree as ET

# ルート要素を作成
root = ET.Element('library')

# 子要素を追加
book1 = ET.SubElement(root, 'book')
book1.set('id', '1')
book1.text = 'The Great Gatsby'

book2 = ET.SubElement(root, 'book')
book2.set('id', '2')
book2.text = 'Moby-Dick'

# XML文書に書き出し
tree = ET.ElementTree(root)
tree.write('library.xml')

新しいXML文書library.xmlを作成し、その中に2つのbook要素を追加しています。

XML要素の検索手法

Pythonでは、ElementTreeを使用して、特定の要素や属性を検索できます。

例として、findallメソッドを使用して、特定のタグを持つ要素を全て検索してみましょう。

import xml.etree.ElementTree as ET

xml = """<data>
    <items>
        <item id="0001">Item 1</item>
        <item id="0002">Item 2</item>
    </items>
</data>"""

root = ET.fromstring(xml)

# 'item'タグを持つ要素を検索
for item in root.findall(".//item"):
    print(item.text)

XMLデータからitemタグを持つ要素を検索し、そのテキスト内容を出力します。

XMLファイルの編集と書き換え

XML要素の属性やテキストを変更したり、新しい要素を追加したりも可能です。

編集した内容をファイルに書き出すには、ElementTreeのwriteメソッドを使用します。

import xml.etree.ElementTree as ET

tree = ET.parse('sample.xml')
root = tree.getroot()

# 属性の変更
for item in root.findall('.//item'):
    item.set('id', 'new_id')

# 新しい要素の追加
new_item = ET.SubElement(root.find('.//items'), 'item')
new_item.set('id', '0003')
new_item.text = 'Item 3'

# ファイルに書き出し
tree.write('sample_modified.xml')

うえのコードでは以下の処理がおこなわれています。

  • sample.xml ファイルを読み込む
  • item タグの id 属性を変更しする
  • 新しい item 要素を追加する
  • 結果を新しいファイルに保存する

名前空間付きXMLの解析スキル

PythonのElementTreeモジュールで、名前空間を扱えます。

名前空間とは、XML文書内でタグの一意性を保持するために使用されるもの。

名前空間を持つXMLの例を見てみましょう。

<root xmlns:book="http://example.com/book">
    <book:title>The Great Gatsby</book:title>
    <book:author>F. Scott Fitzgerald</book:author>
</root>

このXMLでは、bookというプレフィックスが名前空間として定義されています。

名前空間を持つXMLを解析する際は、ElementTreeモジュールのfindfindall、およびfindtextメソッドを使用しましょう。

import xml.etree.ElementTree as ET

xml = """<root xmlns:book="http://example.com/book">
    <book:title>The Great Gatsby</book:title>
    <book:author>F. Scott Fitzgerald</book:author>
</root>"""

# XMLを解析
root = ET.fromstring(xml)

# 名前空間
namespace = {'book': 'http://example.com/book'}

# 名前空間を指定して要素を検索
title = root.find('book:title', namespace)
print(title.text)

名前空間を辞書で定義し、findメソッドに渡すと、名前空間があるXML要素を検索できます。

XPathとその利用方法

こちらでは、XPathの基本とPythonでのXPathの活用方法についてお伝えします。

  • XPathの基本
  • PythonにおけるXPathの活用例
  • Pythonで使用できるXPath構文の解説

XPathの基本

XPathは、XML文書内の要素や属性に対してクエリをおこなうための言語です。

この技術を使用することで、特定の条件に合致する要素を効率的に抽出できます。

XPathはツリー構造に対して柔軟なクエリをサポートし、以下から選択可能です。

  • 単一の要素
  • 属性
  • 要素・属性のグループ

例えば、以下のXPath式は、すべてのauthor要素を選択します。

//author

PythonにおけるXPathの活用例

Pythonのxml.etree.ElementTreeモジュールでは、XPath式を使用してXML文書からデータを抽出できます。

以下はPythonでXPathを使用して、XMLデータから要素を抽出する基本的な例です。

import xml.etree.ElementTree as ET

xml = """
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
   </book>
</catalog>
"""

# XMLを解析
root = ET.fromstring(xml)

# XPathを使用してauthor要素を抽出
for author in root.findall(".//author"):
    print(author.text)

XPath式.//authorを使用して、XML文書内のすべてのauthor要素を検索しています。

Pythonで使用できるXPath構文の解説

XPathには多くの構文があります。以下はPythonで使用できる一般的なXPath構文の例です。

  • * : すべての要素をマッチさせる
  • . : 現在の要素を選択する
  • // : 文書内のあらゆる位置にある要素を選択する
  • [@attrib] : 特定の属性を持つ要素を選択する

これらのXPath構文を組み合わせることで、非常に複雑なクエリを作成できます。

PythonでのXML読み取り

こちらでは、PythonでXMLを読み取る方法について詳しく説明します。

  • 特定要素名のデータ取得方法
  • 配列を用いたデータ取得

特定要素名のデータ取得方法

XML文書から、特定の要素名に一致するデータを取得する方法について見ていきましょう。

XMLデータを解析し、検索や変更のためのオブジェクトを提供する、ElementTreeモジュールを利用します。

以下は簡単な例です。

import xml.etree.ElementTree as ET
tree = ET.parse('sample.xml')
root = tree.getroot()

for child in root:
    if child.tag == 'targetElement':
        print(child.text)

‘sample.xml’というXMLファイルをパースし、すべての子要素を走査します。

要素のタグ名が’targetElement’に一致する場合、その要素のテキスト内容を出力するのです。

配列を用いたデータ取得

XMLの各要素は、配列としてのアクセスも可能です。

XMLのツリー構造を、リストとして扱えます。

XML文書の最初の要素にアクセスし、そのテキストを出力しましょう。

import xml.etree.ElementTree as ET
tree = ET.parse('sample.xml')
root = tree.getroot()

print(root[0].text)

‘sample.xml’の最初の要素のテキスト内容を出力。

Pythonの配列のインデックスは0から始まるため、’root[0]’は最初の要素を参照します。

Python XML関連の関数とオブジェクト

この章では、PythonでXMLを操作するための関数とオブジェクトについて解説します。

  • Pythonで利用できるXML関連の関数
  • 重要なXMLオブジェクトの紹介

Pythonで利用できるXML関連の関数

Pythonのxml.etree.ElementTreeモジュールは、XMLの解析、変更、作成を支援するための多くの関数を提供しています。

例えば、ET.parse()関数はXMLファイルをパースし、その結果をET.ElementTreeオブジェクトとして返すもの。

またET.Element()関数は新たなXML要素を生成し、ET.SubElement()関数は既存のXML要素に新しい子要素を追加します。

import xml.etree.ElementTree as ET

# XMLファイルをパースしてElementTreeオブジェクトを作成
tree = ET.parse('example.xml')
root = tree.getroot()

# 新たなXML要素を生成
new_element = ET.Element('new_element')
new_element.text = 'New Element Text'

# 既存のXML要素に新しい子要素を追加
existing_element = root.find('existing_element')
sub_element = ET.SubElement(existing_element, 'sub_element')
sub_element.text = 'Sub Element Text'

# パースされたXMLを出力
tree.write('output.xml')

重要なXMLオブジェクトの紹介

XMLを扱うにあたっての重要なオブジェクトをご紹介します。

  • ET.ElementTree:XMLの各要素をツリー構造として保持する、XML文書全体を表す
  • ET.Element:XMLの要素を表すオブジェクトで、属性や子要素へのアクセスを提供
  • ET.QName:名前空間付きのXML要素名を表す
  • ET.TreeBuilder:XMLの構築
  • ET.XMLParser:パースを支援

これらのオブジェクトと関数を使って、PythonでXMLを効率的に操作することが可能です。

以下に例を示します。

import xml.etree.ElementTree as ET

# Create a new XML document
root = ET.Element("root")
tree = ET.ElementTree(root)

# Add a new child element
child = ET.SubElement(root, "child")

# Save the XML document
tree.write("output.xml")

新しいXML文書を作成し、その中に”root”と”child”という要素を追加。

その結果を”output.xml”というファイルに書き出しています。

例外処理について

以下のとおり、PythonでXMLを操作する際の例外についてまとめました。

例外名説明対応策
xml.etree.ElementTree.ParseErrorXMLのパース中にエラーが発生した場合の例外XMLの構文を確認し、正しい形式のXMLを使用する
xml.etree.ElementTree.ElementTreeErrorElementTree関連のエラーの基底クラス具体的なエラーメッセージを確認し、問題の原因を特定する
xml.etree.ElementTree.ElementPathSyntaxErrorXPath式の構文エラーが発生した場合の例外XPath式の構文を確認し、正しい形式のXPathを使用する
xml.etree.ElementTree.ElementNotFoundError要素が見つからない場合の例外要素が存在することを確認し、正しい要素名を指定する
xml.etree.ElementTree.XMLSyntaxErrorXMLの構文エラーが発生した場合の例外XMLの構文を確認し、正しい形式のXMLを使用する
xml.etree.ElementTree.XMLParserErrorXMLパーサーによるエラーが発生した場合の例外XMLの構文を確認し、正しい形式のXMLを使用する
IOErrorXMLファイルの読み込みまたは書き込み時のエラーファイルの存在やパスの正確性を確認し、適切なファイルアクセス権を持つ
UnicodeErrorXMLデータのエンコーディングに関連するエラー正しいエンコーディングを指定し、XMLデータを適切に処理する

これらの例外は、XMLのパースや要素の操作中に発生する可能性があります。

以下に例外処理の一例を示します。

import xml.etree.ElementTree as ET

try:
    tree = ET.parse('sample.xml')
except ET.ParseError:
    print("An error occurred while parsing the XML file.")

try-exceptブロックを使用して構文エラーを処理しています。’sample.xml’のパース中にET.ParseErrorが発生した場合、エラーメッセージを出力するものです。

まとめ

当記事でお伝えしてきたことは以下のとおり。

  • ElementTreeモジュールの使い方
  • XMLファイルを読み込み、解析し、XML要素を検索・編集する方法
  • 新しいXML文書を作成する方法
  • 名前空間の扱い方
  • XPathの利用方法
  • 一般的な例外とその対応策

これらの知識を基に、Pythonを使ってXMLデータを自由自在に操作できるようになっていれば幸いです。

XMLはWebサービスやデータ交換フォーマットとして広く使われているため、これらのスキルはWeb開発やデータ分析の領域で役立つでしょう。

これからも、PythonとXMLを使った開発の学習を深めてください。

タイトルとURLをコピーしました