Programación Web y Scripting > Python

 Procesamiento de XML con PYTHON

(1/2) > >>

sonrisitas:
Hola!, les cuento cual es el problema...
Necesito procesar un archivo xml de 500 MB en python, leyendo en la web encontre que libxml2 era apto para cosas grandes. Pero no es asi... ya que en una maquina con 2 G no lo puede procesar, y en un cluster demora 6 horas, necesito urgente si alguien conoce que puedo usar para que no ocupe tanta memoria y para que termine rapido.
Gracias!

RadicalEd:
Puedes abrir el archivo por cantidad de bytes con el método read(cantidad de bytes) ir leyendolo hasta alcanzar el final del fichero, con un ciclo lo podrías llevar hasta el final, algo así:

--- Código: Python ---import osh = os.path.getsize('file.xml') #Se obtiene el tamaño del archivof = open('file.xml', 'r')x = 0while x < h:    f.read(512) #Se va leyendo por cantidad de bytes para no hacer tan pesada la consulta    x += 512  Ojala te sirva.
Chao

su -:
Obviamente la respuesta de Edo no es valida, ya que hacer un parser de XML es un trabajo largo y dificil, y es aun mas dificil cuando tienes que leer bloques de bytes para formar los arboles.

Para ficheros muy grandes, existe SAX (Java) o XML::Twing (Perl) para desarrollo rapido... pero si quieres que el procesamiento sea el mas optimo (en velocidad) lo mejor es libxml (para C) o libxslt (C + Gnome).

El problema es que Python es un poco lento (mas lento que Perl, ya que Python no precompila el codigo como Perl lo hace) y todos los scripts en jeneral... en resumen, lo mejor seria usar C/C++

PD: Espero que no estes usando Windows (los scripts tienden a ser mas lentos).
PD2: Edo, la memoria leida no deberia ser de 512, es muy poquito... deberia ser, al menos, 2Kb  :P

NRM:

--- Cita de: "sonrisitas" ---Hola!, les cuento cual es el problema...
Necesito procesar un archivo xml de 500 MB en python, leyendo en la web encontre que libxml2 era apto para cosas grandes. Pero no es asi... ya que en una maquina con 2 G no lo puede procesar, y en un cluster demora 6 horas, necesito urgente si alguien conoce que puedo usar para que no ocupe tanta memoria y para que termine rapido.
Gracias!
--- Fin de la cita ---

Yo tuve el mismo problema hace un tiempo atras, por lo tanto te voy a comentar mi experiencia.

Los archivos xml que tenia que procesar eran de alrededor de 200MB y cuando los procesaba me consumian mucha memoria.
Despues de investigar note que hay diferentes formas de parsear un xml. Seguramente lo que te esta ocurriendo es lo mismo que me ocurrio a mi, yo utilice DOM[1] para procesar el xml.
El problema es que DOM para procesar el archivo genera un modelo de objetos a partir del xml, por lo tanto en mi caso iba a utilizar mas de 200MB para poder armar el modelo en memoria.
Buscando ayuda encontre otra alternativa llamada SAX[2]. Este en vez de cargar todo en memoria utiliza una api event-driven, que llama metodos segun se abra o cierre un tag.
Por lo tanto SAX podria ser la solucion para tu problema. Aca pongo un ejemplo que es bastante auto explicativo, espero te sirva.


--- Código: Text ---import sys from xml.sax import make_parser, handler class FancyCounter(handler.ContentHandler):     def __init__(self):        self._elems = 0        self._attrs = 0        self._elem_types = {}        self._attr_types = {}     def startElement(self, name, attrs):        self._elems = self._elems + 1        self._attrs = self._attrs + len(attrs)        self._elem_types[name] = self._elem_types.get(name, 0) + 1         for name in attrs.keys():            self._attr_types[name] = self._attr_types.get(name, 0) + 1     def endDocument(self):        print "There were", self._elems, "elements."        print "There were", self._attrs, "attributes."         print "---ELEMENT TYPES"        for pair in  self._elem_types.items():            print "%20s %d" % pair         print "---ATTRIBUTE TYPES"        for pair in  self._attr_types.items():            print "%20s %d" % pair             parser = make_parser()parser.setContentHandler(FancyCounter())parser.parse(sys.argv[1])  

Saludos

nrm

[1] - http://en.wikipedia.org/wiki/Document_Object_Model
[2] - http://en.wikipedia.org/wiki/Simple_API_for_XML

NRM:

--- Cita de: "su -" ---El problema es que Python es un poco lento (mas lento que Perl, ya que Python no precompila el codigo como Perl lo hace) y todos los scripts en jeneral... en resumen, lo mejor seria usar C/C++
--- Fin de la cita ---

En esta pagina[1] tenes informacion sobre el tema de la compilacion de los modulos de python.
Si el problema es la performance se puede extender python utilizando C[2], solo para tener otra opcion.
Esta otra[3] tiene un benchmark sobre ambos lenguajes.

Saludos

nrm

[1] - http://docs.python.org/tut/node8.html#S ... 0000000000
[2] - http://www.python.org/doc/ext/intro.html
[3] - http://shootout.alioth.debian.org/gp4/python.php

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa