Python-XML 処理
前のページ次のページ
XML は移植可能なオープン ソース言語であり、オペレーティング システムや開発言語に関係なく、プログラマーが他のアプリケーションで読み取ることができるアプリケーションを開発できるようにします。
XML とは
Extensible Markup Language (XML) は、HTML や SGML によく似たマークアップ言語です。これは World Wide Web Consortium によって推奨されており、オープン スタンダードとして利用できます。
XML は、SQL ベースのバックボーンを必要とせずに少量から中量のデータを追跡するのに非常に役立ちます。
XML パーサーのアーキテクチャと API
Python 標準ライブラリは、XML を操作するための最小限でありながら便利なインターフェイス セットを提供します。
XML データに対して最も基本的で広く使用されている 2 つの API は、SAX と DOM インターフェースです。
-
XML 用のシンプルな API (SAX) − ここでは、関心のあるイベントのコールバックを登録してから、パーサーにドキュメントを処理させます。これは、ドキュメントが大きい場合やメモリに制限がある場合に便利です。ファイルをディスクから読み取るときに解析し、ファイル全体がメモリに保存されることはありません。
-
ドキュメント オブジェクト モデル (DOM) API − これは World Wide Web Consortium の推奨事項であり、XML ドキュメントのすべての機能を表すために、ファイル全体がメモリに読み込まれ、階層 (ツリーベース) 形式で格納されます。
大きなファイルを扱う場合、SAX が DOM ほど速く情報を処理できないことは明らかです。一方、DOM を排他的に使用すると、特に多数の小さなファイルで使用した場合に、リソースが大量に消費される可能性があります。
SAX は読み取り専用ですが、DOM では XML ファイルを変更できます。これら 2 つの異なる API は文字通り互いに補完し合うため、大規模なプロジェクトで両方を使用できない理由はありません。
すべての XML コード例では、単純な XML ファイル movies.xml を使用しましょう。 入力として −
<collection shelf="New Arrivals"> <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 title="Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A schientific fiction</description> </movie> <movie title="Trigun"> <type>Anime, Action</type> <format>DVD</format> <episodes>4</episodes> <rating>PG</rating> <stars>10</stars> <description>Vash the Stampede!</description> </movie> <movie title="Ishtar"> <type>Comedy</type> <format>VHS</format> <rating>PG</rating> <stars>2</stars> <description>Viewable boredom</description> </movie> </collection>
SAX API を使用した XML の解析
SAX は、イベント ドリブンの XML 解析用の標準インターフェイスです。通常、SAX で XML を解析するには、xml.sax.ContentHandler をサブクラス化して独自の ContentHandler を作成する必要があります。
ContentHandler XML のフレーバーの特定のタグと属性を処理します。 ContentHandler オブジェクトは、さまざまな解析イベントを処理するメソッドを提供します。所有するパーサーは、XML ファイルを解析する際に ContentHandler メソッドを呼び出します。
メソッド startDocument そしてendDocument XML ファイルの最初と最後で呼び出されます。メソッド characters(text) パラメーター text を介して XML ファイルの文字データが渡されます。
ContentHandler は、各要素の開始時と終了時に呼び出されます。パーサーが名前空間モードでない場合、メソッド startElement(tag, attributes) endElement(タグ) 呼び出されます。それ以外の場合は、対応するメソッド startElementNS そしてendElementNS 呼ばれます。ここで、tag は要素タグで、attributes は Attributes オブジェクトです。
先に進む前に理解しておくべきその他の重要な方法を次に示します −
make_parser 方法
次のメソッドは、新しいパーサー オブジェクトを作成して返します。作成されるパーサー オブジェクトは、システムが検出した最初のパーサー タイプになります。
xml.sax.make_parser( [parser_list] )
ここにパラメータの詳細があります −
-
parser_list − 使用するパーサーのリストで構成されるオプションの引数で、すべて make_parser メソッドを実装する必要があります。
パース 方法
次のメソッドは、SAX パーサーを作成し、それを使用してドキュメントを解析します。
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
ここにパラメータの詳細があります −
-
xmlファイル − これは、読み取る XML ファイルの名前です。
-
コンテンツハンドラ − これは ContentHandler オブジェクトでなければなりません。
-
エラーハンドラ − 指定する場合、errorhandler は SAX ErrorHandler オブジェクトでなければなりません。
parseString 方法
SAX パーサーを作成し、指定された XML 文字列 を解析する方法がもう 1 つあります。 .
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
ここにパラメータの詳細があります −
-
xmlstring − これは、読み取る XML 文字列の名前です。
-
コンテンツハンドラ − これは ContentHandler オブジェクトでなければなりません。
-
エラーハンドラ − 指定する場合、errorhandler は SAX ErrorHandler オブジェクトでなければなりません。
例
#!/usr/bin/python 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 = "" # Call when an element starts def startElement(self, tag, attributes): self.CurrentData = tag if tag == "movie": print "*****Movie*****" title = attributes["title"] print "Title:", title # Call when an elements ends 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 = "" # Call when a character is read 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__"): # create an XMLReader parser = xml.sax.make_parser() # turn off namepsaces parser.setFeature(xml.sax.handler.feature_namespaces, 0) # override the default ContextHandler 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 schientific 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 API ドキュメントの詳細については、標準の Python SAX API を参照してください。
DOM API を使用した XML の解析
Document Object Model (「DOM」) は、XML ドキュメントにアクセスして変更するための World Wide Web Consortium (W3C) による言語間 API です。
DOM は、ランダム アクセス アプリケーションに非常に役立ちます。 SAX では、一度にドキュメントの 1 ビットのみを表示できます。 1 つの SAX 要素を見ている場合、別の要素にアクセスすることはできません。
XML ドキュメントをすばやくロードし、xml.dom モジュールを使用して minidom オブジェクトを作成する最も簡単な方法を次に示します。 minidom オブジェクトは、XML ファイルから DOM ツリーをすばやく作成する単純なパーサー メソッドを提供します。
サンプル フレーズは、minidom オブジェクトの parse( file [,parser] ) 関数を呼び出して、file で指定された XML ファイルを DOM ツリー オブジェクトに解析します。
#!/usr/bin/python from xml.dom.minidom import parse import xml.dom.minidom # Open XML document using minidom parser DOMTree = xml.dom.minidom.parse("movies.xml") collection = DOMTree.documentElement if collection.hasAttribute("shelf"): print "Root element : %s" % collection.getAttribute("shelf") # Get all the movies in the collection movies = collection.getElementsByTagName("movie") # Print detail of each movie. for movie in movies: print "*****Movie*****" if movie.hasAttribute("title"): print "Title: %s" % movie.getAttribute("title") type = movie.getElementsByTagName('type')[0] print "Type: %s" % type.childNodes[0].data format = movie.getElementsByTagName('format')[0] print "Format: %s" % format.childNodes[0].data rating = movie.getElementsByTagName('rating')[0] print "Rating: %s" % rating.childNodes[0].data description = movie.getElementsByTagName('description')[0] print "Description: %s" % description.childNodes[0].data
これにより、次の結果が生成されます-
Root element : New Arrivals *****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Rating: PG Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Rating: R Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Description: Viewable boredom
DOM API ドキュメントの詳細については、標準の Python DOM API を参照してください。
Python