Python:Unicode和ElementTree.parse
我正试图转向Python2.7,因为Unicode在那里很重要,我会尝试用XML文件和文本处理它们,并使用Python:Unicode和ElementTree.parse,python,xml,unicode,python-3.x,Python,Xml,Unicode,Python 3.x,我正试图转向Python2.7,因为Unicode在那里很重要,我会尝试用XML文件和文本处理它们,并使用XML.etree.cElementTree库解析它们。但我遇到了这个错误: >>> import xml.etree.cElementTree as ET >>> from io import StringIO >>> source = """\ ... <?xml version="1.0" encoding="UTF-8" s
XML.etree.cElementTree
库解析它们。但我遇到了这个错误:
>>> import xml.etree.cElementTree as ET
>>> from io import StringIO
>>> source = """\
... <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
... <root>
... <Parent>
... <Child>
... <Element>Text</Element>
... </Child>
... </Parent>
... </root>
... """
>>> srcbuf = StringIO(source.decode('utf-8'))
>>> doc = ET.parse(srcbuf)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 56, in parse
File "<string>", line 35, in parse
cElementTree.ParseError: no element found: line 1, column 0
关于unicode和ET解析,我在这里遗漏了什么吗
编辑:显然,ET解析器不能很好地处理unicode输入流?以下工作:
>>> with io.open('test.xml', mode='rb') as fp:
... ET.parse(fp)
...
<ElementTree object at 0x0180BC10>
io.open('test.xml',mode='rb')作为fp的>>:
... ET.parse(fp)
...
但这也意味着如果我想从内存中的文本解析,我不能使用io.StringIO
,除非我先将其编码到内存缓冲区中?你不能使用吗
doc = ET.fromstring(source)
在您的第一个示例中?我在Python 2.6中遇到了与您相同的问题 Python2.x和3.x版本中cElementTree.parse的“utf-8”编码似乎有所不同。在Python2.x中,我们可以使用XMLParser对unicode进行编码。例如:
import xml.etree.cElementTree as etree
parser = etree.XMLParser(encoding="utf-8")
targetTree = etree.parse( "./targetPageID.xml", parser=parser )
pageIds = targetTree.find("categorymembers")
print "pageIds:",etree.tostring(pageIds)
关于XMLParser方法,您可以参考本页(“XMLParser”部分):
以下方法适用于Python 3.x版本:
import xml.etree.cElementTree as etree
import codecs
target_file = codecs.open("./targetPageID.xml",mode='r',encoding='utf-8')
targetTree = etree.parse( target_file )
pageIds = targetTree.find("categorymembers")
print "pageIds:",etree.tostring(pageIds)
希望这能对您有所帮助。您的问题是您正在输入
ElementTree
unicode,但它更喜欢使用字节。在任何情况下,它都将为您提供unicode
在Python2.x中,它只能消耗字节。您可以告诉它这些字节的编码方式,但仅此而已。因此,如果您确实需要处理表示文本文件的对象,如io.StringIO
,首先需要将其转换为其他内容
如果从UTF-8编码的2.x-str
(又称bytes
)开始,在内存中,如您的示例所示,使用xml.etree.celementree.xml
一次性将其解析为xml,不要担心这些:-)
如果您想要一个能够处理从文件增量读取的数据的接口,请使用xml.etree.celementree.parse
和io.BytesIO
将其转换为内存中的字节流,而不是内存中的字符字符串。如果要使用io.open
,请将其与b
标志一起使用,以便获得字节流
在Python3.x中,您可以将unicode直接传递给ElementTree,这有点方便,而且可以说ElementTree的较新版本更适合这样做。但是,您可能仍然不想这样做,并且Python 3的版本仍然接受字节作为输入。无论如何,您总是从字节开始:通过将它们直接从输入源传递到ElementTree,您可以让它在XML解析引擎中智能地进行编码或解码,以及在输入流中动态检测编码声明,这可以用XML实现,但不能用任意文本数据。因此,让XML解析器执行解码工作是正确的责任所在。我没有意识到这个函数的存在。次要的一点是:
fromstring
返回一个元素
,而parse
返回一个ElementTree
。这个函数也称为它的别名,XML
,即从XML.etree.celementree导入XML。如果代码中有一个XML常量,那么这个别名就可以很好地读取;您只需执行fooDocument=XML(“…”)
。XML.etree.cElementTree
模块自python 3.3以来就不受欢迎。看,这有点正确,但是在Python2和Python3之间,ElementTree版本比您认为的更相似。我想我会写一个不同的答案。
import xml.etree.cElementTree as etree
import codecs
target_file = codecs.open("./targetPageID.xml",mode='r',encoding='utf-8')
targetTree = etree.parse( target_file )
pageIds = targetTree.find("categorymembers")
print "pageIds:",etree.tostring(pageIds)