使用Python lxml时出错“加载外部实体失败”

时间:2012-05-04 23:57:54

标签: python xml lxml elementtree

我正在尝试解析从Web检索的XML文档,但在解析此错误后崩溃了:

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

这是下载的XML中的第二行。有没有办法阻止解析器尝试加载外部实体,或者另一种方法来解决这个问题?这是我到目前为止的代码:

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)

4 个答案:

答案 0 :(得分:21)

与mzjn所说的一致,如果你想将字符串传递给etree.parse(),只需将其包装在StringIO对象中。

示例:

from lxml import etree
from StringIO import StringIO

myString = "<html><p>blah blah blah</p></html>"

tree = etree.parse(StringIO(myString))

此方法用于lxml documentation

答案 1 :(得分:11)

etree.parse(source)希望source成为

之一
  • 文件名/路径
  • 文件对象
  • 类文件对象
  • 使用HTTP或FTP协议的URL

问题是您将XML内容作为字符串提供。

您也可以不使用urllib2.urlopen()。只需使用

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

演示(使用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>
>>>   

competing answer中,由于文档中处理指令引用的样式表,建议lxml失败。但这不是问题所在。 lxml不会尝试加载样式表,如果您按上述方法执行,则会解析XML文档。

如果要实际加载样式表,则必须明确它。需要这样的东西:

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()   

答案 2 :(得分:1)

用于解析的lxml文档说要从字符串解析,请改用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).

答案 3 :(得分:0)

您收到该错误,因为您加载的XML引用了外部资源:

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

LXML不知道如何解决GreenButtonDataStyleSheet.xslt。你和我可能已经意识到它将相对于你的原始网址http://www.greenbuttondata.org/data/15MinLP_15Days.xml可用... ...诀窍是告诉lxml如何加载它。

lxml documentation包含标题为“Document loading and URL resolving”的部分,其中包含您需要的所有信息。