creadas con aplicaciones python xml lxml elementtree

aplicaciones creadas con python



Error ''no se pudo cargar la entidad externa'' cuando se usa Python lxml (4)

En concierto con lo que dijo mzjn, si desea pasar una cadena a etree.parse (), simplemente envuélvalo en un objeto StringIO.

Ejemplo:

from lxml import etree from StringIO import StringIO myString = "<html><p>blah blah blah</p></html>" tree = etree.parse(StringIO(myString))

Este método se utiliza en la documentación de lxml .

Estoy tratando de analizar un documento XML que recupero de la web, pero se bloquea después de analizar con este error:

'': failed to load external entity "<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="GreenButtonDataStyleSheet.xslt"?>

Esa es la segunda línea en el XML que se descarga. ¿Hay alguna forma de evitar que el analizador intente cargar la entidad externa u otra forma de resolver esto? Este es el código que tengo hasta ahora:

import urllib2 import lxml.etree as etree file = urllib2.urlopen("http://www.greenbuttondata.org/data/15MinLP_15Days.xml") data = file.read() file.close() tree = etree.parse(data)


Recibes ese error porque el XML que estás cargando hace referencia a un recurso externo:

<?xml-stylesheet type="text/xsl" href="GreenButtonDataStyleSheet.xslt"?>

LXML no sabe cómo resolver GreenButtonDataStyleSheet.xslt . Probablemente, usted y yo nos demos cuenta de que estará disponible en relación a su URL original, http://www.greenbuttondata.org/data/15MinLP_15Days.xml ... el truco es decirle a lxml cómo cargarlo.

La documentación de lxml incluye una sección titulada " Carga de documentos y resolución de URL ", que tiene casi toda la información que necesita.


lxml docs para analizar dice Para analizar desde una cadena, use la función fromstring() lugar.

parse(...) parse(source, parser=None, base_url=None) Return an ElementTree object loaded with source elements. If no parser is provided as second argument, the default parser is used. The ``source`` can be any of the following: - a file name/path - a file object - a file-like object - a URL using the HTTP or FTP protocol To parse from a string, use the ``fromstring()`` function instead. Note that it is generally faster to parse from a file path or URL than from an open file object or file-like object. Transparent decompression from gzip compressed sources is supported (unless explicitly disabled in libxml2).


etree.parse(source) espera que la source sea ​​una de

  • un nombre de archivo / ruta
  • un objeto de archivo
  • un objeto parecido a un archivo
  • una URL usando el protocolo HTTP o FTP

El problema es que está suministrando el contenido XML como una cadena.

También puedes hacerlo sin urllib2.urlopen() . Solo usa

tree = etree.parse("http://www.greenbuttondata.org/data/15MinLP_15Days.xml")

Demostración (usando lxml 2.3.4):

>>> from lxml import etree >>> tree = etree.parse("http://www.greenbuttondata.org/data/15MinLP_15Days.xml") >>> tree.getroot() <Element {http://www.w3.org/2005/Atom}feed at 0xedaa08> >>>

En una respuesta de la competencia , se sugiere que lxml falla debido a la hoja de estilo a la que hace referencia la instrucción de procesamiento en el documento. Pero ese no es el problema aquí. lxml no intenta cargar la hoja de estilo, y el documento XML se analiza bien si lo hace como se describe anteriormente.

Si realmente quieres cargar la hoja de estilo, debes ser explícito al respecto. Se necesita algo como esto:

from lxml import etree tree = etree.parse("http://www.greenbuttondata.org/data/15MinLP_15Days.xml") # Create an _XSLTProcessingInstruction object pi = tree.xpath("//processing-instruction()")[0] # Parse the stylesheet and return an ElementTree xsl = pi.parseXSL()