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

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

The `xml.dom.pulldom` module provides a "pull parser" which can also be asked to produce DOM-accessible fragments of the document where necessary. The basic concept involves pulling "events" from a stream of incoming XML and processing them. In contrast to SAX which also employs an event-driven processing model together with callbacks, the user of a pull parser is responsible for explicitly pulling events from the stream, looping over those events until either processing is finished or an error condition occurs.

注釈

If you need to parse untrusted or unauthenticated data, see XML security.

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

- `START_ELEMENT`

- `END_ELEMENT`

- `COMMENT`

- `START_DOCUMENT`

- `END_DOCUMENT`

- `CHARACTERS`

- `PROCESSING_INSTRUCTION`

- `IGNORABLE_WHITESPACE`

`node` は型 `xml.dom.minidom.Document`、 `xml.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()` を呼び出す前に変更することができます。その場合、その新しい値が有効になります。

## DOMEventStream オブジェクト

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

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

  getEvent()

    event が `START_DOCUMENT` の場合は event と `xml.dom.minidom.Document` としての現在の node からなるタプルを、 `START_ELEMENT` か `END_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()