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

PythonのSAX APIでXMLを解析する方法【初心者向け解説】

SAX(Simple API for XML)は、イベント駆動方式でXMLを解析するための標準インターフェースです。DOMがXML全体をメモリ上に読み込んでから操作するのに対し、SAXはドキュメントを先頭から順に読み進めながら、要素の開始・終了などの「イベント」を発生させて処理を行います。そのため、大きなXMLファイルでもメモリ消費を抑えて高速に処理できるのが特徴です。

PythonでSAXを使ってXMLを解析するには、通常xml.sax.ContentHandlerを継承した独自のハンドラークラスを作成します。

ContentHandlerとは

ContentHandlerは、XML固有のタグや属性に応じた処理を担当するクラスです。このオブジェクトは、さまざまな解析イベントに対応するメソッドを提供し、パーサーがXMLファイルを読み進める過程でこれらのメソッドを自動的に呼び出します。

主なメソッドは以下のとおりです。

  • startDocument / endDocument: XMLファイルの読み込み開始時と終了時にそれぞれ呼び出されます。
  • characters(text): XML内の文字データが、引数textとして渡されます。
  • startElement(tag, attributes) / endElement(tag): 各要素の開始時と終了時に呼び出されます。パーサーが名前空間モードでない場合はこれらのメソッドが使われ、名前空間モードの場合は代わりにstartElementNSおよびendElementNSが呼び出されます。tagは要素のタグ名、attributesはAttributesオブジェクトです。

make_parserメソッド

新しいパーサーオブジェクトを作成して返すメソッドです。生成されるパーサーは、システムが最初に見つけたパーサーの種類になります。

xml.sax.make_parser( [parser_list] )

パラメータの詳細:

  • parser_list: 省略可能な引数。使用するパーサーのリストを指定します。リスト内のすべてのパーサーはmake_parserメソッドを実装している必要があります。

parseメソッド

SAXパーサーを作成し、それを使ってXMLドキュメントを解析するメソッドです。

xml.sax.parse( xmlfile, contenthandler[, errorhandler])

パラメータの詳細:

  • xmlfile: 読み込むXMLファイルの名前です。
  • contenthandler: ContentHandlerオブジェクトを指定します。
  • errorhandler: 指定する場合は、SAXのErrorHandlerオブジェクトである必要があります。

parseStringメソッド

ファイルではなく、指定したXML文字列を解析するためのメソッドもあります。

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

パラメータの詳細:

  • xmlstring: 読み込むXML文字列です。
  • contenthandler: ContentHandlerオブジェクトを指定します。
  • errorhandler: 指定する場合は、SAXのErrorHandlerオブジェクトである必要があります。

実行例

ここでは、映画情報を格納したXML(movies.xml)を解析する例を紹介します。まず、解析対象となるサンプルXMLは次のような構造です。

<collection>
  <movie title="Enemy Behind">
    <type>War, Thriller</type>
    <format>DVD</format>
    <year>2003</year>
    <rating>PG</rating>
    <stars>10</stars>
    <description>Talk about a US-Japan war</description>
  </movie>
  <!-- 以降、同様のmovie要素が続く -->
</collection>

続いて、ContentHandlerを継承したMovieHandlerクラスを作成し、各イベントに応じた処理を実装します(Python 3系の記法)。

#!/usr/bin/python3
import xml.sax

class MovieHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.CurrentData = ""
        self.type = ""
        self.format = ""
        self.year = ""
        self.rating = ""
        self.stars = ""
        self.description = ""

    # 要素の開始時に呼ばれる
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "movie":
            print("*****Movie*****")
            title = attributes["title"]
            print("Title:", title)

    # 要素の終了時に呼ばれる
    def endElement(self, tag):
        if self.CurrentData == "type":
            print("Type:", self.type)
        elif self.CurrentData == "format":
            print("Format:", self.format)
        elif self.CurrentData == "year":
            print("Year:", self.year)
        elif self.CurrentData == "rating":
            print("Rating:", self.rating)
        elif self.CurrentData == "stars":
            print("Stars:", self.stars)
        elif self.CurrentData == "description":
            print("Description:", self.description)
        self.CurrentData = ""

    # 文字データを読み込んだときに呼ばれる
    def characters(self, content):
        if self.CurrentData == "type":
            self.type = content
        elif self.CurrentData == "format":
            self.format = content
        elif self.CurrentData == "year":
            self.year = content
        elif self.CurrentData == "rating":
            self.rating = content
        elif self.CurrentData == "stars":
            self.stars = content
        elif self.CurrentData == "description":
            self.description = content

if __name__ == "__main__":
    # XMLReaderを作成
    parser = xml.sax.make_parser()
    # 名前空間を無効化
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # デフォルトのContentHandlerを差し替え
    handler = MovieHandler()
    parser.setContentHandler(handler)
    parser.parse("movies.xml")

このプログラムを実行すると、次のような結果が出力されます。

*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A scientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom

このように、SAXでは要素の開始・終了・文字データというイベントの流れに沿って処理を記述するため、逐次的なデータ抽出に適しています。SAX APIの詳細については、Python公式ドキュメントの標準SAX APIリファレンスを参照してください。

  1. Pythonの継承とは?単一継承と階層継承の基本をサンプルコードで解説

    本記事では、Python 3.xにおける継承(インヘリタンス)とクラスの拡張方法について詳しく解説します。 継承とは、現実世界のモノや概念の関係性を自然に表現できる、オブジェクト指向プログラミングの中核となる仕組みです。継承を活用すると、次のようなメリットが得られます。 再利用性:すでに書いたコードを流用でき、重複を削減できる 推移性:クラス間の関係を連鎖的に引き継げる 開発速度の向上:ゼロから書かずに済むため、短期間で開発できる 保守性・拡張性:既存クラスを壊さずに機能を追加しやすい 継承の5つの種類 Pythonの継承は、その構造によって主に以下の5種類に分類されます。 単一継承(

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

    Pythonの標準ライブラリに含まれるXMLパーサーは、XMLファイルから必要な情報を読み取り、抽出するための最も手軽な手段のひとつです。このチュートリアルでは、xml.etree.ElementTree(ElementTree XML API)を使って、XMLファイルの「解析」「編集」「新規作成」を行う方法を、実際のコード例とともにわかりやすく解説します。 ElementTreeは、XMLデータの抽出・解析・変換をシンプルに実現できるAPIであり、外部ライブラリをインストールすることなくすぐに使い始められるのが大きな魅力です。 それでは、さっそくElementTreeを使ったPythonのX