xml.dom.pulldom --- 部分的な DOM ツリー構築のサポート

Source code: Lib/xml/dom/pulldom.py


xml.dom.pulldom モジュールは「プルパーザ」を提供し、必要に応じて、文書の一部分を DOM でアクセスできる形で生成するよう要求できます。 基本的な考え方は、入力される XML ストリームから「イベント」を取り出し、それを処理するというものです。 SAX もコールバックを使うイベント駆動の処理モデルを採用していますが、プルパーザでは利用者が明示的にストリームからイベントを取り出します。 利用者は処理が完了するかエラーが起こるまで、イベントを順に処理します。

注釈

信頼できないデータや、認証されていないデータを解析する場合は、XML のセキュリティ を参照してください。

バージョン 3.7.1 で変更: セキュリティを向上させるため、SAX パーサーはデフォルトでは外部一般エンティティを処理しなくなりました。 外部エンティティの処理を有効にするには、次のようにカスタムのパーサーインスタンスを渡します。

from xml.dom.pulldom import parse
from xml.sax import make_parser
from xml.sax.handler import feature_external_ges

parser = make_parser()
parser.setFeature(feature_external_ges, True)
parse(filename, parser=parser)

以下はプログラム例です:

from xml.dom import pulldom

doc = pulldom.parse('sales_items.xml')
for event, node in doc:
    if event == pulldom.START_ELEMENT and node.tagName == 'item':
        if int(node.getAttribute('price')) > 50:
            doc.expandNode(node)
            print(node.toxml())

event は以下の定数のいずれかで、node はイベントの対象となるノードです。 ノードは xml.dom のインターフェースを実装しており、PullDOM に渡された DOM 実装によって作成されます。 デフォルトの実装は xml.dom.minidom です。

xml.dom.pulldom.START_DOCUMENT
xml.dom.pulldom.END_DOCUMENT

文書の開始と終了です。 node は Document です。

xml.dom.pulldom.START_ELEMENT
xml.dom.pulldom.END_ELEMENT

要素の開始タグと終了タグです。 node は Element です。

xml.dom.pulldom.CHARACTERS

文字データです。 node は Text ノードです。

xml.dom.pulldom.IGNORABLE_WHITESPACE

DTD の宣言に基づく、要素内容中の空白です。 node は Text ノードです。

xml.dom.pulldom.COMMENT

コメントです。 node は Comment ノードです。

xml.dom.pulldom.PROCESSING_INSTRUCTION

処理命令です。 node は ProcessingInstruction ノードです。

文書を「平坦な」イベントの流れとして扱うため、文書の「木」は暗黙的に走査され、木の中の深さにかかわらず目的の要素を見つけられます。 つまり、文書ノードを再帰的に検索するなど、階層構造を考慮する必要はありません。 ただし、要素の文脈が重要な場合は、文脈に関する状態を管理する (文書中のどの位置にいるかを常に記憶する) か、 DOMEventStream.expandNode() メソッドを使って DOM による処理に切り替える必要があります。

class xml.dom.pulldom.PullDOM(documentFactory=None)

SAX イベントをプルパーザのイベントに変換する、xml.sax.handler.ContentHandler のサブクラスです。 ノードは作成しますが、expandNode() を呼び出さない限り木には追加しません。 documentFactory を指定する場合は、文書を作成するための DOM 実装を渡します。 デフォルトでは xml.dom.minidom の実装を使います。

class xml.dom.pulldom.SAX2DOM(documentFactory=None)

作成したノードをすべて木にも追加して完全な文書を構築する、PullDOM のサブクラスです。

xml.dom.pulldom.parse(stream_or_string, parser=None, bufsize=None)

与えられた入力から DOMEventStream を返します。stream_or_string はファイル名かファイル様オブジェクトのいずれかです。parser は、与えれた場合、 XMLReader オブジェクトでなければなりません。この関数はパーザの文書ハンドラを変えて名前空間のサポートを有効にします。パーザの他の設定 (例えばエンティティリゾルバ) は前もってしておかなければなりません。

XML データを文字列で持っている場合、 parseString() を代わりに使うことができます:

xml.dom.pulldom.parseString(string, parser=None)

string を表す DOMEventStream を返します。 string は str インスタンスでなければなりません。 バイト列を解析するには、バイナリファイルオブジェクトを parse() に渡してください。

xml.dom.pulldom.default_bufsize

parse() の bufsize パラメタのデフォルト値です。

この変数の値は parse() を呼び出す前に変更することができます。その場合、その新しい値が有効になります。

DOMEventStream オブジェクト

class xml.dom.pulldom.DOMEventStream(stream, parser, bufsize)

XMLReader である parser がファイルオブジェクト stream から読み取ったデータに対するイベントを生成します。 データは一度に bufsize バイトずつ (テキストストリームの場合は文字数) 読み取ります。

バージョン 3.11 で変更: __getitem__() メソッドのサポートは削除されました。

getEvent()

次の (event, node) タプルを返します。 文書の末尾では None を返します。 イベントと対応するノードについては上記を参照してください。 expandNode() を呼び出さない限り、現在のノードには子ノードの情報が含まれません。

expandNode(node)

node の全子ノードを node に展開します。例:

from xml.dom import pulldom

xml = '<html><title>Foo</title> <p>Some text <div>and more</div></p> </html>'
doc = pulldom.parseString(xml)
for event, node in doc:
    if event == pulldom.START_ELEMENT and node.tagName == 'p':
        # 次の文は '<p/>' だけを表示する。
        print(node.toxml())
        doc.expandNode(node)
        # 次の文はすべての子を含むノード '<p>Some text <div>and more</div></p>' を表示する。
        print(node.toxml())
reset()

まだ読み取っていないイベントを破棄し、新しい文書の解析に向けてオブジェクトを準備します。

clear()

パーザと文書を解放します。 ストリームは閉じませんが、このオブジェクトは以後使用できなくなります。