J'essaie d'analyser un document XML que je récupère sur le Web, mais il se bloque après l'analyse avec cette erreur:
': failed to load external entity "<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="GreenButtonDataStyleSheet.xslt"?>
C'est la deuxième ligne du XML qui est téléchargée. Existe-t-il un moyen d’empêcher l’analyseur d’essayer de charger l’entité externe ou un autre moyen de résoudre ce problème? C'est le code que j'ai jusqu'à présent:
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)
En accord avec ce que mzjn a dit, si vous voulez passer une chaîne à etree.parse (), enroulez-la simplement dans un objet StringIO.
Exemple:
from lxml import etree
from StringIO import StringIO
myString = "<html><p>blah blah blah</p></html>"
tree = etree.parse(StringIO(myString))
Cette méthode est utilisée dans la documentation lxml .
etree.parse(source)
s'attend à ce que source
soit l’un des
Le problème est que vous fournissez le contenu XML sous forme de chaîne.
Vous pouvez également vous passer de urllib2.urlopen()
. Juste utiliser
tree = etree.parse("http://www.greenbuttondata.org/data/15MinLP_15Days.xml")
Démonstration (en utilisant 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>
>>>
Dans un réponse concurrente , il est suggéré que lxml échoue en raison de la feuille de style référencée par l'instruction de traitement dans le document. Mais ce n'est pas le problème ici. lxml n'essaie pas de charger la feuille de style et le document XML est analysé correctement si vous procédez comme décrit ci-dessus.
Si vous voulez réellement charger la feuille de style, vous devez être explicite à ce sujet. Quelque chose comme ceci est nécessaire:
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()
documents lxml pour parse dit Pour analyser une chaîne, utilisez plutôt la fonction fromstring()
.
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).
Vous obtenez cette erreur car le XML que vous chargez fait référence à une ressource externe:
<?xml-stylesheet type="text/xsl" href="GreenButtonDataStyleSheet.xslt"?>
LXML ne sait pas comment résoudre GreenButtonDataStyleSheet.xslt
. Vous et moi-même réalisons probablement qu'il sera disponible par rapport à votre URL d'origine, http://www.greenbuttondata.org/data/15MinLP_15Days.xml
... l'astuce consiste à dire à lxml
comment s'y prendre pour le charger.
La documentation lxml comprend une section intitulée " Chargement de document et résolution d'URL ", qui contient à peu près toutes les informations dont vous avez besoin.