你正在放置一个[text()]过滤器,该过滤器只显示那些有文本节点的元素......然后当你没有给出没有文本节点的元素时你会不高兴吗?
保留该过滤器,您将获得您的模型元素:
>>> s='''
...
...
... Blue
... Chevy
...
...
... '''
>>> e = lxml.etree.fromstring(s)
>>> carData = e.xpath('Car/node()')
>>> carData
[, , ]
>>> dict(((e.tag, e.text) for e in carData))
{'Color': 'Blue', 'Make': 'Chevy', 'Model': None}也就是说 - 如果您的直接目标是迭代树中的节点,您可以考虑使用lxml.etree.iterparse(),这将避免尝试在内存中构建完整的DOM树,否则比构建树然后迭代更有效使用XPath。 (想想SAX,但没有疯狂和痛苦的API)。
使用iterparse实现可能如下所示:
def get_cars(infile):
in_car = False
current_car = {}
for (event, element) in lxml.etree.iterparse(infile, events=('start', 'end')):
if event == 'start':
if element.tag == 'Car':
in_car = True
current_car = {}
continue
if not in_car: continue
if element.tag == 'Car':
yield current_car
continue
current_car[element.tag] = element.text
for car in get_cars(infile = cStringIO.StringIO('''BlueChevy''')):
print car...它是更多的代码,但是(如果我们没有使用StringIO作为示例)它可以处理比内存中更大的文件。