代码之家  ›  专栏  ›  技术社区  ›  Santa

Python:Unicode和ElementTree.parse

  •  10
  • Santa  · 技术社区  · 16 年前

    我正在尝试转移到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" 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
    

    io.open('filename.xml', encoding='utf-8') 传递给 ET.parse

    >>> with io.open('test.xml', mode='w', encoding='utf-8') as fp:
    ...     fp.write(source.decode('utf-8'))
    ...
    150L
    >>> with io.open('test.xml', mode='r', encoding='utf-8') as fp:
    ...     fp.read()
    ...
    u'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n<root>\n  <Parent>\n
        <Child>\n      <Element>Text</Element>\n    </Child>\n  </Parent>\n</root>\n
    '
    >>> with io.open('test.xml', mode='r', encoding='utf-8') as fp:
    ...     ET.parse(fp)
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, 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.StringIO 如果我想从内存中的文本进行解析,除非我首先将其编码到内存缓冲区中?

    3 回复  |  直到 16 年前
        1
  •  4
  •   Andre Holzner    16 年前

    你不能用吗

    doc = ET.fromstring(source)
    

    在你的第一个例子里?

        2
  •  15
  •   Glyph    14 年前

    你的问题是你在喂食 ElementTree unicode,但它 偏好 消耗字节。会的 提供

    在Python2.x中,它可以 消耗字节数。你可以告诉它这些字节是用什么编码的,但就是这样。所以,如果你真的要处理一个代表 文本文件 ,就像 io.StringIO ,首先需要将其转换为其他内容。

    str (又名 bytes )在UTF-8编码中,在内存中,如您的示例中所示,使用 xml.etree.cElementTree.XML

    如果您想要一个可以处理从文件中增量读取的数据的接口,请使用 xml.etree.cElementTree.parse 带着一个 io.BytesIO io.open ,与 b 标记,以便获得字节流。

    在Python3.x中,您 可以

        3
  •  7
  •   shanethehat    14 年前

    似乎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”部分): http://effbot.org/zone/elementtree-13-intro.htm

    以下方法适用于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)