2009-01-25 24 views
9

Estoy tratando de dividir un gran archivo XML en bits más pequeños. Me gustaría escanear el archivo buscando una etiqueta específica, luego tomar toda la información entre y, luego guardarla en un archivo, luego continuar con el resto del archivo.División de un archivo XML grande en Python

Mi problema está tratando de encontrar una manera limpia señalar el comienzo y el final de las etiquetas, de modo que pueda agarrar el texto dentro como puedo escanear a través del archivo con "para la línea de f"

I' d no usar variables centinelas. ¿Hay alguna forma pitónica de hacer esto?

El archivo es demasiado grande para leer en la memoria.

+1

Trate http://stackoverflow.com/search?q=iterparse – jfs

+0

si utiliza jython y JVM de 64 bits, puede utilizar extendida ETV-xml para hacer la división, la más elegante// tipo eficiente sencilla –

Respuesta

6

Puede considerar utilizar la función ElementTree iterparse para esta situación.

+0

elementtree está en stdlib – jfs

+1

Gracias Jeff - no solo domesticó un problema de memoria, sino que ahora tengo 3 líneas de código en lugar de 20 –

9

Existen dos formas comunes de manejar datos XML.

Uno se llama DOM, que significa Document Object Model. Este estilo de análisis XML es probablemente lo que ha visto al examinar la documentación, ya que lee todo el XML en la memoria para crear el modelo de objetos.

El segundo se llama SAX, que es un método de transmisión. El analizador comienza a leer el XML y envía señales a su código sobre ciertos eventos, p. cuando se encuentra una nueva etiqueta de inicio.

Así que SAX es claramente lo que necesita para su situación. Los analizadores de Sax se pueden encontrar en la biblioteca de python bajo xml.sax y xml.parsers.expat.

+0

+1: descomposición de SAX de documentos XML grandes. –

+0

vtd-xml es mucho mejor que dom o sax –

+1

Me parece que vtd-xml es DOM.Puedes llamarlo "acceso aleatorio" o "centrado en el documento", pero eso sigue siendo DOM. Parece que vtd-xml tiene un fuerte análisis e indexación, pero sigue siendo DOM. –

1

¡Cómo serendipitous! Will Larson acaba de hacer una buena publicación sobre Handling Very Large CSV and XML File in Python.

Las principales conclusiones parecen ser el uso del módulo xml.sax, como mencionó Van, y para realizar algunas macro-funciones para abstraer los detalles de la API SAX de bajo nivel.

6

He tenido éxito con el método cElementTree.iterparse para realizar una tarea similar.

Tenía un documento xml grande con 'entradas' repetidas con la etiqueta 'resFrame' y quería filtrar las entradas para una identificación específica. Aquí está el código que he utilizado para ello:

documento de origen tuvo esta estructura

<snapDoc> 
    <bucket>....</bucket> 
    <bucket>....</bucket> 
    <bucket>....</bucket> 
    ... 
    <resFrame><id>234234</id>.....</resFrame> 
    <frame><id>344234</id>.....</frame> 
    <resFrame>...</resFrame> 
    <frame>...</frame> 
</snapDoc> 

que utilizó la siguiente secuencia de comandos para crear un documento más pequeño que tenía la misma estructura, las entradas de cubo y sólo las entradas resFrame con una identificación específica

#!/usr/bin/env python2.6 

import xml.etree.cElementTree as cElementTree 
start = '''<?xml version="1.0" encoding="UTF-8"?> 
<snapDoc>''' 

def main(): 
    print start 
    context = cElementTree.iterparse('snap.xml', events=("start", "end")) 
    context = iter(context) 
    event, root = context.next() # get the root element of the XML doc 

    for event, elem in context: 
     if event == "end": 
      if elem.tag == 'bucket': # i want to write out all <bucket> entries 
       elem.tail = None 
       print cElementTree.tostring(elem) 
      if elem.tag == 'resFrame': 
       if elem.find("id").text == ":4:39644:482:-1:1": # i only want to write out resFrame entries with this id 
        elem.tail = None 
        print cElementTree.tostring(elem) 
      if elem.tag in ['bucket', 'frame', 'resFrame']: 
       root.clear() # when done parsing a section clear the tree to safe memory 
    print "</snapDoc>" 

main() 
0

Este es un viejo, pero muy buen artículo de también muy buena columna XML Python & de Uche Ogbuji. Cubre su pregunta exacta y utiliza el módulo de sax estándar de lib como lo sugirió la otra respuesta. Decomposition, Process, Recomposition

Cuestiones relacionadas