我编写了一个小函数,该函数使用ElementTree和xpath提取xml文件中某些元素的文本内容:

#!/usr/bin/env python2.5

import doctest
from xml.etree import ElementTree
from StringIO import StringIO

def parse_xml_etree(sin, xpath):
  """
Takes as input a stream containing XML and an XPath expression.
Applies the XPath expression to the XML and returns a generator
yielding the text contents of each element returned.

>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem1').next()
'one'
>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem2').next()
'two'
>>> parse_xml_etree(
...   StringIO('<test><null>&#0;</null><elem3>three</elem3></test>'),
...   '//elem2').next()
'three'
"""

  tree = ElementTree.parse(sin)
  for element in tree.findall(xpath):
    yield element.text

if __name__ == '__main__':
  doctest.testmod(verbose=True)

第三次测试失败,但有以下异常:

ExpatError:引用无效字符编号:第1行,第13列
&#0;实体是否为非法XML?不管是否,我要解析的文件都包含它,并且我需要某种方式来解析它们。对于除Expat以外的其他解析器的建议或对Expat的设置,有什么建议可以允许我这样做?

更新:我刚刚发现了BeautifulSoup,这是一个标记汤解析器,如下面的答案注释中所述,为了好玩,我回到了这个问题,并尝试将其用作ElementTree之前的XML清洁器,但是它忠实地转换了&#0;变成无效的空字节。 :-)
cleaned_s = StringIO(
  BeautifulStoneSoup('<test><null>&#0;</null><elem3>three</elem3></test>',
                     convertEntities=BeautifulStoneSoup.XML_ENTITIES
  ).renderContents()
)
tree = ElementTree.parse(cleaned_s)

...产量
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12

但是,在我的特定情况下,我实际上并不需要XPath解析,我可以使用BeautifulSoup本身及其非常简单的节点地址样式parsed_tree.test.elem1.contents[0]

最佳答案

&#0;不在XML规范定义的legal character range中。 las,我的Python技能很初级,所以我在这里没有太多帮助。

关于Python + Expat : Error on &#0; entities,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3038798/

10-10 12:58