我编写了一个小函数,该函数使用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>�</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列
�
实体是否为非法XML?不管是否,我要解析的文件都包含它,并且我需要某种方式来解析它们。对于除Expat以外的其他解析器的建议或对Expat的设置,有什么建议可以允许我这样做?更新:我刚刚发现了BeautifulSoup,这是一个标记汤解析器,如下面的答案注释中所述,为了好玩,我回到了这个问题,并尝试将其用作ElementTree之前的XML清洁器,但是它忠实地转换了
�
变成无效的空字节。 :-)cleaned_s = StringIO(
BeautifulStoneSoup('<test><null>�</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]
。 最佳答案
�
不在XML规范定义的legal character range中。 las,我的Python技能很初级,所以我在这里没有太多帮助。
关于Python + Expat : Error on � entities,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3038798/