首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python支持解析未知的ElementTree实体吗?

Python支持解析未知的ElementTree实体吗?
EN

Stack Overflow用户
提问于 2011-08-30 08:17:39
回答 2查看 23.1K关注 0票数 21

我有一组超级简单的XML文件要解析...但是..。它们使用自定义的实体。我不需要将这些映射到字符,但我确实希望对每个字符进行解析和操作。例如:

代码语言:javascript
复制
<Style name="admin-5678">
    <Rule>
      <Filter>[admin_level]='5'</Filter>
      &maxscale_zoom11;
    </Rule>
</Style>

http://effbot.org/elementtree/elementtree-xmlparser.htm上有一个诱人的暗示,XMLParser的实体支持有限,但我找不到提到的方法,所有的方法都会出错:

代码语言:javascript
复制
    #!/usr/bin/python
    ##
    ## Where's the entity support as documented at:
    ## http://effbot.org/elementtree/elementtree-xmlparser.htm
    ## In Python 2.7.1+ ?
    ##
    from pprint     import pprint
    from xml.etree  import ElementTree
    from cStringIO  import StringIO

    parser = ElementTree.ElementTree()
   #parser.entity["maxscale_zoom11"] = unichr(160)
    testf = StringIO('<foo>&maxscale_zoom11;</foo>')
    tree = parser.parse(testf)
   #tree = parser.parse(testf,"XMLParser")
    for node in tree.iter('foo'):
        print node.text

这取决于您调整注释的方式:

代码语言:javascript
复制
xml.etree.ElementTree.ParseError: undefined entity: line 1, column 5

代码语言:javascript
复制
AttributeError: 'ElementTree' object has no attribute 'entity'

代码语言:javascript
复制
AttributeError: 'str' object has no attribute 'feed'           

对于那些好奇的人来说,XML来自于OpenStreetMap的mapnik项目。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-01 09:26:31

我不确定这是不是ElementTree中的错误,但您需要在expat解析器上调用UseForeignDTD(True),才能像过去那样运行。

这有点老生常谈,但您可以通过创建自己的ElementTree.Parser实例,在其xml.parsers.expat实例上调用该方法,然后将其传递给ElementTree.parse()来实现:

代码语言:javascript
复制
from xml.etree  import ElementTree
from cStringIO  import StringIO


testf = StringIO('<foo>&moo_1;</foo>')

parser = ElementTree.XMLParser()
parser.parser.UseForeignDTD(True)
parser.entity['moo_1'] = 'MOOOOO'

etree = ElementTree.ElementTree()

tree = etree.parse(testf, parser=parser)

for node in tree.iter('foo'):
    print node.text

这会输出"MOOOOO“

或者使用映射接口:

代码语言:javascript
复制
from xml.etree  import ElementTree
from cStringIO  import StringIO

class AllEntities:
    def __getitem__(self, key):
        #key is your entity, you can do whatever you want with it here
        return key

testf = StringIO('<foo>&moo_1;</foo>')

parser = ElementTree.XMLParser()
parser.parser.UseForeignDTD(True)
parser.entity = AllEntities()

etree = ElementTree.ElementTree()

tree = etree.parse(testf, parser=parser)

for node in tree.iter('foo'):
    print node.text

这将输出"moo_1“

一个更复杂的修复方法是创建ElementTree.XMLParser的子类并在那里修复它。

票数 13
EN

Stack Overflow用户

发布于 2016-02-24 09:17:34

正如@cnelson已经在评论中指出的那样,这里选择的解决方案在Python3中不起作用。

我终于把它修好了。引用自此Q&A

this post的启发,我们只需在传入的原始HTML内容前添加一些XML定义,然后ElementTree就可以开箱即用了。

这对Python 2.6、2.7、3.3、3.4都有效。

代码语言:javascript
复制
import xml.etree.ElementTree as ET

html = '''<html>
    <div>Some reasonably well-formed HTML content.</div>
    <form action="login">
    <input name="foo" value="bar"/>
    <input name="username"/><input name="password"/>

    <div>It is not unusual to see &nbsp; in an HTML page.</div>

    </form></html>'''

magic = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
            <!ENTITY nbsp ' '>
            ]>'''  # You can define more entities here, if needed

et = ET.fromstring(magic + html)
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7237466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档