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

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


xml.dom.pulldom モジュールは "プルパーザ" を提供します。 プルパーザは必要に応じて文書の DOM アクセス可能な断片を生成することができます。 基本概念は、入力 XML のストリームから "イベント" を取り出し (pull し) て処理することです。 SAX とは、コールバックつきのイベント駆動処理モデルを採用しているという点で同様ですが、SAX とは対照的に、プルパーザの使用者には処理が完了するかエラー状態が発生するまで、明示的にストリームからイベントを取り出し、イベントに対しループを回す責任があります。

警告

xml.dom.pulldom モジュールは悪意を持って作成されたデータに対して安全ではありません。信頼できないデータや認証されていないデータをパースする必要がある場合は XML の脆弱性 を参照してください。

バージョン 3.6.7 で変更: 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 は定数で以下の内の一つです:

  • START_ELEMENT

  • END_ELEMENT

  • COMMENT

  • START_DOCUMENT

  • END_DOCUMENT

  • CHARACTERS

  • PROCESSING_INSTRUCTION

  • IGNORABLE_WHITESPACE

node は型 xml.dom.minidom.Documentxml.dom.minidom.Element または xml.dom.minidom.Text のオブジェクトです。

文書はイベントの フラットな 流れとして扱われるため、文書の "木" は暗黙のうちに全て読み込まれ、目的の要素は木の中の深さに依らずに見つけられます。つまり、文書ノードの再帰的な検索のような階層的な問題を考える必要はありません。しかしながら要素の前後関係が重要な場合は、前後関係の状態を維持する (すなわち文章中の任意の点の場所を記憶する) か、 DOMEventStream.expandNode() メソッドを使用して DOM 関連の処理に切り替える必要があります。

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

xml.sax.handler.ContentHandler のサブクラスです。

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

xml.sax.handler.ContentHandler のサブクラスです。

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 を返します。

xml.dom.pulldom.default_bufsize

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

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

20.8.1. DOMEventStream オブジェクト

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

event が START_DOCUMENT の場合は eventxml.dom.minidom.Document としての現在の node からなるタプルを、 START_ELEMENTEND_ELEMENT の場合は xml.dom.minidom.Element を、 CHARACTERS の場合は xml.dom.minidom.Text を返します。 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':
        # Following statement only prints '<p/>'
        print(node.toxml())
        doc.expandNode(node)
        # Following statement prints node with all its children '<p>Some text <div>and more</div></p>'
        print(node.toxml())
reset()