library - Procesamiento XML en Python
xml python 3 (12)
Estoy a punto de construir una parte de un proyecto que necesitará construir y publicar un documento XML en un servicio web y me gustaría hacerlo en Python, como un medio para expandir mis habilidades en él.
Desafortunadamente, aunque conozco bastante bien el modelo XML en .NET, no estoy seguro de cuáles son los pros y los contras de los modelos XML en Python.
¿Alguien tiene experiencia haciendo procesamiento XML en Python? ¿Por dónde sugerirías que empiece? Los archivos XML que construiré serán bastante simples.
Para un trabajo serio con XML en Python, use lxml
Python viene con la biblioteca incorporada ElementTree, pero lxml lo extiende en términos de velocidad y funcionalidad (validación de esquema, análisis saxo, XPath, varios tipos de iteradores y muchas otras características).
Debe instalarlo, pero en muchos lugares ya se supone que forma parte del equipo estándar (por ejemplo, Google AppEngine no permite paquetes Python basados en C, pero hace una excepción para lxml, pyyaml y algunos otros).
Creación de documentos XML con E-factory (desde lxml)
Su pregunta es sobre la creación de documentos XML.
Con lxml hay muchos métodos y me llevó un tiempo encontrar uno, que parece ser fácil de usar y también fácil de leer.
Código de muestra de lxml doc al usar E-factory (ligeramente simplificado):
E-factory proporciona una sintaxis simple y compacta para generar XML y HTML:
>>> from lxml.builder import E
>>> html = page = (
... E.html( # create an Element called "html"
... E.head(
... E.title("This is a sample document")
... ),
... E.body(
... E.h1("Hello!"),
... E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
... E.p("This is another paragraph, with a", "/n ",
... E.a("link", href="http://www.python.org"), "."),
... E.p("Here are some reserved characters: <spam&egg>."),
... )
... )
... )
>>> print(etree.tostring(page, pretty_print=True))
<html>
<head>
<title>This is a sample document</title>
</head>
<body>
<h1>Hello!</h1>
<p>This is a paragraph with <b>bold</b> text in it!</p>
<p>This is another paragraph, with a
<a href="http://www.python.org">link</a>.</p>
<p>Here are some reserved characters: <spam&egg>.</p>
</body>
</html>
Agradezco en E-factory que siga las cosas
El código se lee casi como el documento XML resultante
La legibilidad cuenta.
Permite la creación de cualquier contenido XML
Soporta cosas como:
- uso de espacios de nombres
- inicio y finalización de nodos de texto dentro de un elemento
- funciones que dan formato al contenido del atributo (vea CLASE func en la muestra completa de lxml )
Permite construcciones muy legibles con listas
p.ej:
from lxml import etree
from lxml.builder import E
lst = ["alfa", "beta", "gama"]
xml = E.root(*[E.record(itm) for itm in lst])
etree.tostring(xml, pretty_print=True)
Resultando en:
<root>
<record>alfa</record>
<record>beta</record>
<record>gama</record>
</root>
Conclusiones
Le recomiendo leer el tutorial lxml: está muy bien escrito y le dará muchas más razones para usar esta poderosa biblioteca.
La única desventaja de lxml es que debe compilarse. Consulte la respuesta SO para obtener más consejos sobre cómo instalar lxml desde el paquete de formato de rueda en una fracción de segundo.
Como mencionó que creará XML "bastante simple", el módulo minidom (parte de la Biblioteca estándar de Python) probablemente se adaptará a sus necesidades. Si tiene alguna experiencia con la representación DOM de XML, debería encontrar la API bastante sencilla.
Depende un poco de lo complicado que deba ser el documento.
He usado mucho minidom para escribir XML, pero eso generalmente ha sido solo leer documentos, hacer algunas transformaciones simples y volver a escribirlos. Eso funcionó lo suficientemente bien hasta que necesité la capacidad de ordenar atributos de elementos (para satisfacer una aplicación antigua que no analiza XML correctamente). En ese momento me di por vencido y escribí el XML yo mismo.
Si solo está trabajando en documentos simples, hacerlo usted mismo puede ser más rápido y sencillo que aprender un marco. Si puede escribir el XML a mano, entonces probablemente también pueda codificarlo a mano (solo recuerde escapar correctamente de caracteres especiales y use str.encode(codec, errors="xmlcharrefreplace")
). Además de estos problemas, XML es lo suficientemente regular como para que no necesite una biblioteca especial para escribirlo. Si el documento es demasiado complicado para escribirlo a mano, entonces probablemente debería examinar uno de los marcos ya mencionados. En ningún momento debe escribir un escritor XML general.
Escribo un servidor SOAP que recibe solicitudes XML y crea respuestas XML. (Desafortunadamente, no es mi proyecto, por lo que es de código cerrado, pero ese es otro problema).
Resultó para mí que crear documentos XML (SOAP) es bastante simple si tienes una estructura de datos que "se ajusta" al esquema.
Guardo el sobre ya que el sobre de respuesta es (casi) el mismo que el sobre de solicitud. Luego, dado que mi estructura de datos es un diccionario (posiblemente anidado), creo una cadena que convierte este diccionario en elementos <key> value </key>.
Esta es una tarea que hace que la recursión sea simple, y termino con la estructura correcta. Todo esto se hace en código python y actualmente es lo suficientemente rápido para uso en producción.
También puede (relativamente) crear fácilmente listas, aunque, dependiendo de su cliente, puede encontrar problemas a menos que brinde sugerencias de longitud.
Para mí, esto fue mucho más simple, ya que un diccionario es una forma mucho más fácil de trabajar que una clase personalizada. Para los libros, ¡generar XML es mucho más fácil que analizar!
Hay 3 formas principales de tratar con XML, en general: dom, sax y xpath. El modelo dom es bueno si puede permitirse cargar todo su archivo xml en la memoria de una vez, y no le importa tratar con estructuras de datos, y está viendo gran parte del modelo. El modelo saxo es excelente si solo le importan unas pocas etiquetas, y / o si se trata de archivos grandes y puede procesarlos secuencialmente. El modelo xpath es un poco de cada uno: puede elegir rutas de acceso a los elementos de datos que necesita, pero requiere más bibliotecas para usar.
Si quieres ser sencillo y empaquetado con Python, minidom es tu respuesta, pero es bastante lamentable, y la documentación es "aquí hay documentos sobre dom, descifra". Es muy molesto.
Personalmente, me gusta cElementTree, que es una implementación más rápida (basada en c) de ElementTree, que es un modelo tipo dom.
He usado sistemas de saxo, y en muchos sentidos son más "pitónicos" en su sensación, pero generalmente termino creando sistemas basados en estado para manejarlos, y de esa manera se encuentra la locura (y los errores).
Digo ir con minidom si te gusta la investigación, o ElementTree si quieres un buen código que funcione bien.
He usado ElementTree para varios proyectos y lo recomiendo.
Es pitónico, viene ''en la caja'' con Python 2.5, incluida la versión c cElementTree (xml.etree.cElementTree), que es 20 veces más rápido que la versión pura de Python, y es muy fácil de usar.
lxml tiene algunas ventajas de rendimiento, pero son desiguales y primero debe verificar los puntos de referencia para su caso de uso.
Según tengo entendido, el código de ElementTree se puede portar fácilmente a lxml.
Personalmente, he jugado con varias de las opciones integradas en un proyecto con gran cantidad de XML y me he decidido por pulldom como la mejor opción para documentos menos complejos.
Especialmente para cosas pequeñas y simples, me gusta la teoría de análisis basada en eventos en lugar de configurar una gran cantidad de devoluciones de llamada para una estructura relativamente simple. Aquí hay una buena discusión rápida sobre cómo usar la API .
Lo que me gusta: puede manejar el análisis en un bucle for
lugar de usar devoluciones de llamada. También retrasa el análisis completo (la parte "pull") y solo obtiene detalles adicionales cuando llama a expandNode()
. Esto satisface mi requisito general de eficiencia "responsable" sin sacrificar la facilidad de uso y la simplicidad.
Recomiendo encarecidamente la implementación de SAX - Simple API for XML
) en las bibliotecas de Python. Son bastante fáciles de configurar y procesar XML
gran tamaño incluso mediante API
controlada, como se discutió en los pósters anteriores aquí, y tienen poca huella de memoria a diferencia de la validación de analizadores XML
estilo DOM
.
Si vas a construir mensajes SOAP, echa un vistazo a soaplib . Utiliza ElementTree debajo del capó, pero proporciona una interfaz mucho más limpia para serializar y deserializar mensajes.
Supongo que la forma .Net de procesar XML se basa en alguna versión de MSXML y, en ese caso, supongo que usar, por ejemplo, minidom te hará sentir como en casa. Sin embargo, si se trata de un procesamiento simple, probablemente esté haciendo cualquier biblioteca.
También prefiero trabajar con ElementTree cuando trato con xml en Python, es una biblioteca muy ordenada.
También puede intentar untangle para analizar documentos XML simples.
ElementTree tiene una buena API de Pythony. Creo que incluso se envía como parte de Python 2.5
Está en Python puro y, como digo, bastante agradable, pero si lxml necesitando más rendimiento, entonces lxml expone la misma API y usa libxml2 bajo el capó. Teóricamente, puede cambiarlo cuando descubra que lo necesita.