解析 XML 文档时的格式为:
<Car>
<Color>Blue</Color>
<Make>Chevy</Make>
<Model>Camaro</Model>
</Car>
我使用以下代码:
carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]')
parsedCarData = [{field.tag: field.text for field in carData} for action in carData]
print parsedCarData[0]['Color'] #Blue
如果标签为空,则此代码将不起作用,例如:
<Car>
<Color>Blue</Color>
<Make>Chevy</Make>
<Model/>
</Car>
使用与上面相同的代码:
carData = element.xpath('//Root/Foo/Bar/Car/node()[text()]')
parsedCarData = [{field.tag: field.text for field in carData} for action in carData]
print parsedCarData[0]['Model'] #Key Error
我将如何解析这个空白标签。
你正在输入一个[text()]
过滤器明确只要求具有文本节点的元素...然后当它没有为您提供没有文本节点的元素时您会感到不高兴?
保留该过滤器,您将获得模型元素:
>>> s='''
... <root>
... <Car>
... <Color>Blue</Color>
... <Make>Chevy</Make>
... <Model/>
... </Car>
... </root>'''
>>> e = lxml.etree.fromstring(s)
>>> carData = e.xpath('Car/node()')
>>> carData
[<Element Color at 0x23a5460>, <Element Make at 0x23a54b0>, <Element Model at 0x23a5500>]
>>> 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('''<root><Car><Color>Blue</Color><Make>Chevy</Make><Model/></Car></root>''')):
print car
...这是更多的代码,但是(如果我们没有使用 StringIO 作为示例)它可以处理比内存容量大得多的文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)