【Python】XMLで子要素を取得する方法

この記事では、Pythonを使ってXMLデータを扱う方法について解説します。

具体的には、XMLデータを読み込んで解析し、特定の子要素を取得する方法を学びます。

Pythonの標準ライブラリであるxml.etree.ElementTreeminidom、そして強力な外部ライブラリであるlxmlを使った実践的な例を紹介します。

これを読むことで、XMLデータの基本的な操作方法を理解し、実際のプロジェクトで活用できるようになります。

初心者の方でもわかりやすいように、サンプルコードとその解説を交えながら進めていきますので、安心して読み進めてください。

目次から探す

xml.etree.ElementTreeを使ったXMLのパース

PythonでXMLを扱う際に便利なライブラリの一つがxml.etree.ElementTreeです。

このライブラリを使うことで、XMLファイルの読み込みや解析、子要素の取得などが簡単に行えます。

ここでは、ElementTreeの基本操作からルート要素の取得方法までを解説します。

ElementTreeの基本操作

XMLファイルの読み込み

まずは、XMLファイルを読み込む方法を見ていきましょう。

以下のサンプルコードでは、sample.xmlというファイルを読み込みます。

import xml.etree.ElementTree as ET
# XMLファイルの読み込み
tree = ET.parse('sample.xml')
root = tree.getroot()
# ルート要素のタグ名を表示
print(root.tag)

このコードでは、ET.parseメソッドを使ってXMLファイルを読み込み、getrootメソッドでルート要素を取得しています。

取得したルート要素のタグ名を表示することで、正しく読み込めたかを確認できます。

文字列からのXMLパース

次に、文字列からXMLをパースする方法を見てみましょう。

以下のサンプルコードでは、XML形式の文字列を直接パースしています。

import xml.etree.ElementTree as ET
# XML文字列
xml_data = '''
<root>
    <child>data</child>
</root>
'''
# 文字列からXMLをパース
root = ET.fromstring(xml_data)
# ルート要素のタグ名を表示
print(root.tag)

このコードでは、ET.fromstringメソッドを使ってXML文字列をパースし、ルート要素を取得しています。

こちらも同様に、ルート要素のタグ名を表示して確認できます。

ルート要素の取得

XMLをパースした後、ルート要素を取得することが基本となります。

ルート要素はXMLドキュメントの最上位に位置する要素であり、他のすべての要素はこのルート要素の子要素となります。

先ほどの例でも示したように、getrootメソッドを使うことでルート要素を簡単に取得できます。

# ルート要素の取得
root = tree.getroot()

ルート要素の確認方法

ルート要素を取得したら、その内容を確認することが重要です。

ルート要素のタグ名や属性、子要素などを確認することで、XMLドキュメントの構造を理解できます。

以下のサンプルコードでは、ルート要素のタグ名と属性を表示しています。

# ルート要素のタグ名を表示
print(f'ルート要素のタグ名: {root.tag}')
# ルート要素の属性を表示
print(f'ルート要素の属性: {root.attrib}')

また、ルート要素の子要素を確認する方法も見てみましょう。

# ルート要素の子要素を表示
for child in root:
    print(f'子要素のタグ名: {child.tag}, 子要素の属性: {child.attrib}')

このようにして、ルート要素およびその子要素の情報を取得することで、XMLドキュメントの内容を詳細に確認することができます。

以上が、xml.etree.ElementTreeを使ったXMLのパースとルート要素の取得方法についての基本的な解説です。

次のセクションでは、子要素の取得方法について詳しく見ていきます。

子要素の取得方法

XMLデータをパースした後、特定の子要素を取得する方法について解説します。

Pythonの標準ライブラリであるxml.etree.ElementTreeを使用して、さまざまな方法で子要素を取得する方法を見ていきましょう。

直接子要素の取得

findメソッドの使用

findメソッドは、指定したタグ名の最初の子要素を取得するために使用します。

以下の例では、XMLデータから特定の子要素を取得する方法を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <child1>Value1</child1>
    <child2>Value2</child2>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 'child1'タグの最初の子要素を取得
child1 = root.find('child1')
print(child1.text)  # 出力: Value1

findallメソッドの使用

findallメソッドは、指定したタグ名のすべての子要素をリストとして取得します。

以下の例では、複数の子要素を取得する方法を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <child>Value1</child>
    <child>Value2</child>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 'child'タグのすべての子要素を取得
children = root.findall('child')
for child in children:
    print(child.text)
# 出力:
# Value1
# Value2

特定のタグの子要素の取得

タグ名を指定して取得

特定のタグ名を指定して子要素を取得する場合、findfindallメソッドを使用します。

以下の例では、特定のタグ名を持つ子要素を取得する方法を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <item>Item1</item>
    <item>Item2</item>
    <other>Other1</other>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 'item'タグのすべての子要素を取得
items = root.findall('item')
for item in items:
    print(item.text)
# 出力:
# Item1
# Item2

属性を指定して取得

特定の属性を持つ子要素を取得する場合、XPathを使用することができます。

以下の例では、特定の属性を持つ子要素を取得する方法を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <item id="1">Item1</item>
    <item id="2">Item2</item>
    <item id="3">Item3</item>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 'id'属性が'2'の子要素を取得
item = root.find(".//item[@id='2']")
print(item.text)  # 出力: Item2

子要素のテキスト内容の取得

textプロパティの使用

子要素のテキスト内容を取得するには、textプロパティを使用します。

以下の例では、子要素のテキスト内容を取得する方法を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <child>Value1</child>
    <child>Value2</child>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 'child'タグのすべての子要素を取得
children = root.findall('child')
for child in children:
    print(child.text)
# 出力:
# Value1
# Value2

このように、xml.etree.ElementTreeを使用することで、XMLデータから特定の子要素を簡単に取得することができます。

次に、子要素をループ処理する方法について解説します。

子要素のループ処理

XMLデータを扱う際、すべての子要素をループで取得することがよくあります。

Pythonのxml.etree.ElementTreeモジュールを使えば、簡単に子要素をループで処理することができます。

ここでは、iterメソッドiterfindメソッドを使った方法、そしてネストされた子要素を再帰的に取得する方法について解説します。

すべての子要素をループで取得

iterメソッドの使用

iterメソッドは、指定したタグ名のすべての子要素を取得するために使用されます。

タグ名を指定しない場合は、すべての子要素が取得されます。

以下に、iterメソッドを使った例を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <child1>Text1</child1>
    <child2>Text2</child2>
    <child3>Text3</child3>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# すべての子要素をループで取得
for elem in root.iter():
    print(elem.tag, elem.text)

このコードを実行すると、以下のような出力が得られます。

root 
child1 Text1
child2 Text2
child3 Text3

iterfindメソッドの使用

iterfindメソッドは、指定したパスに一致するすべての子要素を取得するために使用されます。

XPathのようなパスを指定することができます。

以下に、iterfindメソッドを使った例を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <child1>Text1</child1>
    <child2>Text2</child2>
    <child3>Text3</child3>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 特定のタグの子要素をループで取得
for elem in root.iterfind('child2'):
    print(elem.tag, elem.text)

このコードを実行すると、以下のような出力が得られます。

child2 Text2

ネストされた子要素の取得

XMLデータはしばしばネストされた構造を持っています。

ネストされた子要素を再帰的に取得する方法について解説します。

再帰的な取得方法

再帰的に子要素を取得するためには、再帰関数を使用します。

以下に、再帰関数を使ってネストされた子要素を取得する例を示します。

import xml.etree.ElementTree as ET
# サンプルXMLデータ
xml_data = '''<root>
    <parent>
        <child1>Text1</child1>
        <child2>Text2</child2>
        <child3>
            <subchild1>SubText1</subchild1>
            <subchild2>SubText2</subchild2>
        </child3>
    </parent>
</root>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# 再帰的に子要素を取得する関数
def recursive_print(element):
    print(element.tag, element.text)
    for child in element:
        recursive_print(child)
# ルート要素から再帰的に子要素を取得
recursive_print(root)

このコードを実行すると、以下のような出力が得られます。

root 
parent 
child1 Text1
child2 Text2
child3 
subchild1 SubText1
subchild2 SubText2

このようにして、再帰的にネストされた子要素を取得することができます。

再帰関数を使うことで、深くネストされたXMLデータでも簡単に処理することができます。

minidomを使ったXMLのパース

Pythonの標準ライブラリには、XMLを扱うためのモジュールがいくつかあります。

その中でもminidomは、DOM(Document Object Model)を使ってXMLを操作するためのモジュールです。

minidomを使うことで、XML文書をツリー構造として扱い、要素の追加や削除、属性の操作などが簡単に行えます。

minidomの基本操作

まずは、minidomを使ってXMLをパースする基本的な方法を見ていきましょう。

XMLファイルの読み込み

XMLファイルを読み込むには、xml.dom.minidomモジュールのparse関数を使用します。

以下に、XMLファイルを読み込む例を示します。

from xml.dom import minidom
# XMLファイルを読み込む
doc = minidom.parse('example.xml')
# ルート要素を取得
root = doc.documentElement
print(root.tagName)

このコードでは、example.xmlというファイルを読み込み、ルート要素を取得してそのタグ名を表示しています。

文字列からのXMLパース

XML文字列を直接パースする場合は、parseString関数を使用します。

以下に例を示します。

from xml.dom import minidom
# XML文字列を定義
xml_str = """
<root>
    <child id="1">First Child</child>
    <child id="2">Second Child</child>
</root>
"""
# XML文字列をパース
doc = minidom.parseString(xml_str)
# ルート要素を取得
root = doc.documentElement
print(root.tagName)

このコードでは、XML文字列をパースし、ルート要素を取得してそのタグ名を表示しています。

子要素の取得方法

次に、minidomを使ってXMLの子要素を取得する方法を見ていきましょう。

getElementsByTagNameメソッドの使用

特定のタグ名を持つすべての子要素を取得するには、getElementsByTagNameメソッドを使用します。

以下に例を示します。

from xml.dom import minidom
# XML文字列を定義
xml_str = """
<root>
    <child id="1">First Child</child>
    <child id="2">Second Child</child>
</root>
"""
# XML文字列をパース
doc = minidom.parseString(xml_str)
# 'child'タグを持つすべての要素を取得
children = doc.getElementsByTagName('child')
# 各子要素のタグ名とテキスト内容を表示
for child in children:
    print(f'Tag: {child.tagName}, Text: {child.firstChild.data}')

このコードでは、childタグを持つすべての要素を取得し、それぞれのタグ名とテキスト内容を表示しています。

getAttributeメソッドの使用

特定の属性を持つ子要素を取得するには、getAttributeメソッドを使用します。

以下に例を示します。

from xml.dom import minidom
# XML文字列を定義
xml_str = """
<root>
    <child id="1">First Child</child>
    <child id="2">Second Child</child>
</root>
"""
# XML文字列をパース
doc = minidom.parseString(xml_str)
# 'child'タグを持つすべての要素を取得
children = doc.getElementsByTagName('child')
# 各子要素の'id'属性を表示
for child in children:
    print(f'Tag: {child.tagName}, ID: {child.getAttribute("id")}')

このコードでは、childタグを持つすべての要素を取得し、それぞれのid属性を表示しています。

以上が、minidomを使ったXMLのパースと子要素の取得方法です。

minidomを使うことで、XML文書を簡単に操作することができます。

次に、lxmlを使ったXMLのパース方法について見ていきましょう。

lxmlを使ったXMLのパース

lxmlは、PythonでXMLやHTMLを処理するための強力なライブラリです。

lxmlは、ElementTree APIを拡張し、XPathやXSLTなどの高度な機能を提供します。

ここでは、lxmlを使ってXMLをパースし、子要素を取得する方法について解説します。

lxmlの基本操作

インストール方法

まず、lxmlを使用するためには、ライブラリをインストールする必要があります。

以下のコマンドを使用してインストールできます。

pip install lxml

XMLファイルの読み込み

lxmlを使ってXMLファイルを読み込む方法は非常に簡単です。

以下のコード例を見てみましょう。

from lxml import etree
# XMLファイルを読み込む
tree = etree.parse('example.xml')
root = tree.getroot()
# ルート要素を表示
print(root.tag)

このコードでは、example.xmlというファイルを読み込み、ルート要素を取得して表示しています。

文字列からのXMLパース

lxmlを使って文字列からXMLをパースすることも可能です。

以下の例を見てみましょう。

from lxml import etree
# XML文字列
xml_string = """
<root>
    <child1>Content1</child1>
    <child2>Content2</child2>
</root>
"""
# 文字列からXMLをパース
root = etree.fromstring(xml_string)
# ルート要素を表示
print(root.tag)

このコードでは、XML文字列をパースし、ルート要素を取得して表示しています。

子要素の取得方法

XPathを使った取得

lxmlの強力な機能の一つに、XPathを使った要素の取得があります。

XPathは、XML文書内の要素や属性を指定するための言語です。

以下の例を見てみましょう。

from lxml import etree
# XML文字列
xml_string = """
<root>
    <child1>Content1</child1>
    <child2>Content2</child2>
</root>
"""
# 文字列からXMLをパース
root = etree.fromstring(xml_string)
# XPathを使って子要素を取得
child1 = root.xpath('//child1')[0]
print(child1.text)  # Output: Content1

このコードでは、XPathを使ってchild1要素を取得し、そのテキスト内容を表示しています。

CSSセレクタを使った取得

lxmlでは、CSSセレクタを使って要素を取得することも可能です。

以下の例を見てみましょう。

from lxml import etree
from lxml.cssselect import CSSSelector
# XML文字列
xml_string = """
<root>
    <child1>Content1</child1>
    <child2>Content2</child2>
</root>
"""
# 文字列からXMLをパース
root = etree.fromstring(xml_string)
# CSSセレクタを使って子要素を取得
sel = CSSSelector('child1')
child1 = sel(root)[0]
print(child1.text)  # Output: Content1

このコードでは、CSSセレクタを使ってchild1要素を取得し、そのテキスト内容を表示しています。

以上が、lxmlを使ったXMLのパースと子要素の取得方法です。

lxmlは非常に強力で柔軟なライブラリなので、ぜひ活用してみてください。

実践例

ここでは、実際にPythonを使ってXMLデータから子要素を取得する方法を具体的に見ていきます。

まずはサンプルのXMLデータを準備し、それぞれのライブラリを使った子要素の取得方法を解説します。

サンプルXMLデータの準備

以下のようなサンプルXMLデータを使用します。

このデータは、書籍の情報を含んでいます。

<library>
    <book id="1">
        <title>Python入門</title>
        <author>山田太郎</author>
        <year>2020</year>
    </book>
    <book id="2">
        <title>Python中級</title>
        <author>鈴木一郎</author>
        <year>2021</year>
    </book>
    <book id="3">
        <title>Python上級</title>
        <author>佐藤花子</author>
        <year>2022</year>
    </book>
</library>

このXMLデータを使って、各ライブラリで子要素を取得する方法を見ていきます。

xml.etree.ElementTreeを使った子要素の取得例

まずは、標準ライブラリであるxml.etree.ElementTreeを使って子要素を取得する方法を見ていきます。

import xml.etree.ElementTree as ET
# XMLデータを文字列として読み込む
xml_data = '''<library>
    <book id="1">
        <title>Python入門</title>
        <author>山田太郎</author>
        <year>2020</year>
    </book>
    <book id="2">
        <title>Python中級</title>
        <author>鈴木一郎</author>
        <year>2021</year>
    </book>
    <book id="3">
        <title>Python上級</title>
        <author>佐藤花子</author>
        <year>2022</year>
    </book>
</library>'''
# XMLデータをパース
root = ET.fromstring(xml_data)
# すべてのbook要素を取得
books = root.findall('book')
# 各book要素の子要素を取得して表示
for book in books:
    title = book.find('title').text
    author = book.find('author').text
    year = book.find('year').text
    print(f'Title: {title}, Author: {author}, Year: {year}')

このコードを実行すると、以下のような出力が得られます。

Title: Python入門, Author: 山田太郎, Year: 2020
Title: Python中級, Author: 鈴木一郎, Year: 2021
Title: Python上級, Author: 佐藤花子, Year: 2022

minidomを使った子要素の取得例

次に、minidomを使って子要素を取得する方法を見ていきます。

from xml.dom import minidom
# XMLデータを文字列として読み込む
xml_data = '''<library>
    <book id="1">
        <title>Python入門</title>
        <author>山田太郎</author>
        <year>2020</year>
    </book>
    <book id="2">
        <title>Python中級</title>
        <author>鈴木一郎</author>
        <year>2021</year>
    </book>
    <book id="3">
        <title>Python上級</title>
        <author>佐藤花子</author>
        <year>2022</year>
    </book>
</library>'''
# XMLデータをパース
dom = minidom.parseString(xml_data)
# すべてのbook要素を取得
books = dom.getElementsByTagName('book')
# 各book要素の子要素を取得して表示
for book in books:
    title = book.getElementsByTagName('title')[0].firstChild.data
    author = book.getElementsByTagName('author')[0].firstChild.data
    year = book.getElementsByTagName('year')[0].firstChild.data
    print(f'Title: {title}, Author: {author}, Year: {year}')

このコードを実行すると、以下のような出力が得られます。

Title: Python入門, Author: 山田太郎, Year: 2020
Title: Python中級, Author: 鈴木一郎, Year: 2021
Title: Python上級, Author: 佐藤花子, Year: 2022

lxmlを使った子要素の取得例

最後に、lxmlを使って子要素を取得する方法を見ていきます。

lxmlは外部ライブラリなので、事前にインストールが必要です。

pip install lxml

インストールが完了したら、以下のコードを実行します。

from lxml import etree
# XMLデータを文字列として読み込む
xml_data = '''<library>
    <book id="1">
        <title>Python入門</title>
        <author>山田太郎</author>
        <year>2020</year>
    </book>
    <book id="2">
        <title>Python中級</title>
        <author>鈴木一郎</author>
        <year>2021</year>
    </book>
    <book id="3">
        <title>Python上級</title>
        <author>佐藤花子</author>
        <year>2022</year>
    </book>
</library>'''
# XMLデータをパース
root = etree.fromstring(xml_data)
# すべてのbook要素を取得
books = root.findall('book')
# 各book要素の子要素を取得して表示
for book in books:
    title = book.find('title').text
    author = book.find('author').text
    year = book.find('year').text
    print(f'Title: {title}, Author: {author}, Year: {year}')

このコードを実行すると、以下のような出力が得られます。

Title: Python入門, Author: 山田太郎, Year: 2020
Title: Python中級, Author: 鈴木一郎, Year: 2021
Title: Python上級, Author: 佐藤花子, Year: 2022

以上で、xml.etree.ElementTreeminidom、およびlxmlを使ったXMLデータからの子要素の取得方法について解説しました。

それぞれのライブラリには特徴があり、用途に応じて使い分けることが重要です。

目次から探す