Python XML processing
Autor: Marco Minas | Publicado: 2013-10-26T15:18:00-07:00

Sample of read a XML and find data no XML elements.

The XML sample file

<?xml version="1.0" encoding="UTF-8"?>

    
        0
        0
    
    
        
            data-config.xml
            uuid
        
    
    status
    idle
    
    
        5
        5916
        0
        2013-10-22 13:23:29
        Indexing completed. Added/Updated: 5916 documents. Deleted 0 documents.
        2013-10-22 13:23:34
        5916
        0:0:25.461
    
    This response format is experimental.  It is likely to change in the future.



The "wait_status_change.conf" log configuration file

[loggers]
keys=root

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=myFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=myFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=myFormatter
args=('wait_status_change.log', 'a', 4096, 5)

[formatter_myFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%m-%d %H:%M


The "wait_status_change.py" Python script

#!/usr/bin/python
# -*- coding: utf-8 -*-
'''Processa um XML retornado pelo servidor em busca de um status especifico.
Enquanto o status esperado for igual a "busy" o processo aguarda 
por 2 segundos e tenta novamente refazer a leitura do servidor.

Para testar com arquivo em disco edite o XML de exemplo enquanto executa
o script.'''

__author__ = 'Marco Antonio Almeida'
__version__ = '0.0.1'
__date__ = '26 out 2013'

import xml.etree.ElementTree as et
import time
import os

# Inicializando componente de log.
import logging
import logging.config
import logging.handlers
logging.config.fileConfig('wait_status_change.conf')
logger = logging.getLogger()
#

def read_file(fn):
    '''Retorna todo o conteudo de um arquivo. Problemas com acesso 
 ou leitura do arquivo vao gerar erros'''
    with open(fn) as f:
        return f.read()
#end def

def obter_resposta_do_servidor():
    '''Obtem o XML e retorna um "xml.etree.ElementTree.Element" com 
 o resultado.'''
    response = read_file('wait_status_change.xml')
    logger.debug(response)

    root = et.fromstring(response)
    logger.debug(type(root))

    return root

#end def

def traduzir_resposta_do_servidor(root):
    '''Recebe um "xml.etree.ElementTree.Element", procura um elemento 
    do tipo "str" e nome "status" e retorna seu valor se o encontrar.'''
    
    logger.debug('Indentificando status retornado pelo servidor')
    node = root.find(".//str[@name='status']")
    logger.debug(type(node))
    
    status = None
    logger.debug('Obtendo o atributos do retorno')
    if node != None:
       status = node.text
    
    return status

#end def

def aguardar_fim_processo():
    '''Faz um loop obtendo o resultado do servidor, aguardando que 
    o status mude de "busy" para o de concluido.'''
    
    logger.info('Aguardando execucao do autosuggest...')
    
    try:
        #time.sleep(1)
        while True:
            
            logger.debug('Obtendo XML do servidor')
            xml = obter_resposta_do_servidor()
            
            logger.debug('Processando resposta do servidor')
            status = traduzir_resposta_do_servidor(xml)
            
            logger.info('Status atual: ' + status)
            
            if status == 'busy':
                logger.info('Aguardando alterar status...')
                time.sleep(2)
                
            else:
                node = xml.find(".//lst[@name='statusMessages']")
                logger.debug(type(node))
                logger.debug(node)
                return et.tostringlist(node)
            
    except Exception as e:
        logger.debug("Erro aguardando resposta, traceback =", exc_info=True)
        return 'autosuggest fail'
    else:
        return 'autosuggest sucess'

#end def

def main():
    '''Executa as operacoes necessarias para leitura de xml'''
    
    logger.info('Iniciando processo.')
    
    try:
        
        # Faz a leitura de um XML
        result = aguardar_fim_processo()
        logger.info(result)
        
    except Exception as e:
        
        logger.debug("Erro aguardando resposta, traceback =", exc_info=True)
        
    time.sleep(3)

#end def

# Executando a aplicacao.
if __name__ == '__main__':
    
    main()
    
#end def