# 20.8. `xml.dom.pulldom` - 支持构建部分DOM树

源代码： Lib / xml / dom / pulldom.py

`xml.dom.pulldom`模块提供了一个“pull解析器”，如果需要，也可以要求它生成文档的DOM可访问的片段。基本概念涉及从传入XML流中拉出“事件”并处理它们。与还使用事件驱动处理模型和回调的SAX相反，拉解析器的用户负责从流中显式拉出事件，循环这些事件直到处理完成或出现错误条件。

警告

`xml.dom.pulldom`模块对于恶意构建的数据不安全。如果需要解析不受信任或未经身份验证的数据，请参阅XML vulnerabilities。

例：

    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可以是文件名或类似文件的对象。解析器（如果给定）必须是`XMLReader`对象。此函数将更改解析器的文档处理程序并激活命名空间支持；其他解析器配置（如设置实体解析器）必须提前完成。

如果在字符串中有XML，可以使用`parseString()`函数：

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

  返回表示（Unicode）字符串的`DOMEventStream`。

`xml.dom.pulldom.``default_bufsize`

  bufsize参数到`parse()`的默认值。

  在调用`parse()`之前，可以更改此变量的值，新值将生效。

## 20.8.1. DOMEventStream Objects

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

    如果event等于`START_DOCUMENT`，则返回包含事件和当前节点的元组为`xml.dom.minidom.Document` `xml.dom.minidom.Element` if event equals `START_ELEMENT`或`END_ELEMENT`或`xml.dom.minidom.Text` if事件等于`CHARACTERS`。除非调用`expandNode()`，否则当前节点不包含有关其子节点的信息。

  `expandNode`(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`()