"xml.dom.pulldom" --- Suporte para construir árvores parciais de DOM
********************************************************************

**Código-fonte:** 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.

Nota:

  Se você precisar analisar dados não confiáveis ou não autenticados,
  consulte Segurança no XML.

Alterado na versão 3.7.1: O analisador sintático de SAX não processa
mais entidades externas gerais por padrão para aumentar a segurança.
Para habilitar o processamento de entidades externas, passe uma
instância personalizada do analisador sintático em:

   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)

Exemplo:

   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" é uma constante e pode ser um de:

* "START_ELEMENT"

* "END_ELEMENT"

* "COMMENT"

* "START_DOCUMENT"

* "END_DOCUMENT"

* "CHARACTERS"

* "PROCESSING_INSTRUCTION"

* "IGNORABLE_WHITESPACE"

"node" é um objeto do tipo "xml.dom.minidom.Document",
"xml.dom.minidom.Element" ou "xml.dom.minidom.Text".

Como o documento é tratado como um fluxo "plano" de eventos, a
"árvore" do documento é implicitamente percorrida e os elementos
desejados são encontrados independentemente de sua profundidade na
árvore. Em outras palavras, não é necessário considerar questões
hierárquicas, como a busca recursiva dos nós do documento, embora, se
o contexto dos elementos fosse importante, seria necessário manter
algum estado relacionado ao contexto (ou seja, lembrar onde se está no
documento em um determinado ponto) ou utilizar o método
"DOMEventStream.expandNode()" e alternar para o processamento
relacionado ao DOM.

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

   Subclasse de "xml.sax.handler.ContentHandler".

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

   Subclasse de "xml.sax.handler.ContentHandler".

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

   Retorna um "DOMEventStream" da entrada fornecida.
   *stream_or_string* pode ser um nome de arquivo ou um objeto arquivo
   ou similar. *parser*, se fornecido, deve ser um objeto "XMLReader".
   Esta função alterará o manipulador de documentos do analisador e
   ativará o suporte a espaços de nomes; outras configurações do
   analisador sintático (como a definição de um resolvedor de
   entidades) devem ter sido feitas previamente.

Se você tiver XML em uma string, poderá usar a função "parseString()":

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

   Retorna um "DOMEventStream" que representa a *string* (Unicode).

xml.dom.pulldom.default_bufsize

   Valor padrão para o parâmetro *bufsize* para "parse()".

   O valor desta variável pode ser alterado antes de chamar "parse()"
   e o novo valor entrará em vigor.


Objetos DOMEventStream
======================

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

   Alterado na versão 3.11: O suporte para o método "__getitem__()"
   foi removido

   getEvent()

      Retorna uma tupla contendo evento *event* e o nó *node* atual
      como "xml.dom.minidom.Document" se o evento for igual a
      "START_DOCUMENT", "xml.dom.minidom.Element" se o evento for
      igual a "START_ELEMENT" ou "END_ELEMENT" ou
      "xml.dom.minidom.Text" se o evento for igual a "CHARACTERS". O
      nó atual não contém informações sobre seus filhos, a menos que
      "expandNode()" seja chamado.

   expandNode(node)

      Expande todos os filhos de *node* para *node*. Exemplo:

         from xml.dom import pulldom

         xml = '<html><title>Foo</title> <p>Algum texto <div>e mais</div></p> </html>'
         doc = pulldom.parseString(xml)
         for event, node in doc:
             if event == pulldom.START_ELEMENT and node.tagName == 'p':
                 # A seguinte instrução só exibe '<p/>'
                 print(node.toxml())
                 doc.expandNode(node)
                 # A seguinte instrução exibe o nó com todos os seus filhos '<p>Algum texto <div>e mais</div></p>'
                 print(node.toxml())

   reset()
