30

我正在尝试解析从 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

4 回答 4

30

与 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 文档中使用。

于 2012-10-20T01:13:14.110 回答
15

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

在一个竞争的答案中,建议 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()   
于 2012-05-06T10:14:39.530 回答
4

lxml docs for parse 说要从字符串中解析,请改用该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).
于 2013-06-25T20:00:35.377 回答
2

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

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

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

lxml 文档包括一个标题为“文档加载和 URL 解析”的部分,其中包含您需要的所有信息。

于 2012-05-05T00:38:49.020 回答