我有一些XML,其片段如下:
<osgb:departedMember>
<osgb:DepartedFeature fid='osgb4000000024942964'>
<osgb:boundedBy>
<gml:Box srsName='osgb:BNG'>
<gml:coordinates>188992.575,55981.029 188992.575,55981.029</gml:coordinates>
</gml:Box>
</osgb:boundedBy>
<osgb:theme>Road Network</osgb:theme>
<osgb:reasonForDeparture>Deleted</osgb:reasonForDeparture>
<osgb:deletionDate>2014-02-19</osgb:deletionDate>
</osgb:DepartedFeature>
</osgb:departedMember>
我正在解析它:
departedmembers = doc_root.findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}departedMember')
for departedMember in departedMembers:
findWhat='{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}DepartedFeature'
fid = int(departedmember.find(findWhat).attrib['fid'].replace('osgb', ''))
theme=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}theme')[0].text
reason=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}reasonForDeparture')[0].text
date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text
有时,原因或日期或两者都是空的,即元素缺失,而不仅仅是空内容。根据XSD,这是合法的,但是我试图选择不存在的元素的文本时会出现属性错误。为了解决这个问题,我把理由和日期行放在了try中,除了块之外,比如:
try:
date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text
except:
pass
这很有效,但是我讨厌使用除了/这样的传递,所以它让我想知道是否有更好的方法来解析这样的文档,其中一些元素是可选的。
答案 0 :(得分:5)
由于您只对findall
的第一个元素感兴趣,因此可以将findall(x)[0]
替换为find(x)
。此外,如果你想避免try / except块,你可以使用三元组。
departedmembers = doc_root.findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}departedMember')
for departedMember in departedMembers:
...
date = departedmember[0].find('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')
date = None if date == None else date.text # Considering you want to set the element to None if it was not found
答案 1 :(得分:2)
是的,问题不在于搜索方法,而是在没有返回元素的情况下引用返回元素。您可以像这样编写代码:
results = departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')
if results:
date = results[0].text
else:
# there is no element,
# do what you want in this case