Python 处理xml文档中缺少的元素

Python 处理xml文档中缺少的元素,python,xml,xml.etree,Python,Xml,Xml.etree,我有一些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>

我有一些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>
有时,原因或日期或两者都是空的,即元素丢失,而不仅仅是内容为空。根据XSD,这是合法的,但我在尝试选择不存在元素的文本时遇到属性错误。为了解决这个问题,我在try中添加了原因行和日期行,但块除外,如:

try:
    date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text
except:
    pass

这是可行的,但我不喜欢像这样使用except/pass,因此我想知道是否有更好的方法来解析这样的文档,其中某些元素是可选的。

是的,问题不是搜索方法,而是在没有返回元素时对返回元素的引用。您可以这样编写代码:

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

是的,问题不是搜索方法,而是在没有返回元素时对返回元素的引用。您可以这样编写代码:

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

因为您只对findall的第一个元素感兴趣,所以可以用findx替换findallx[0]。此外,如果要避免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

因为您只对findall的第一个元素感兴趣,所以可以用findx替换findallx[0]。此外,如果要避免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

这肯定比try/except更干净。不过,我在想,这是解析大型xml文档的最佳方法,还是应该在xmltree中使用xpath之类的东西。@JohnBarça,我发现xpath更容易理解maintain@Luis,谢谢,我很快会试试的。我匆忙地解析了千兆字节的XML,在很短的时间内了解非常优秀的xmltree库的各种复杂之处非常有趣。这肯定比try/except更简洁。不过,我在想,这是解析大型xml文档的最佳方法,还是应该在xmltree中使用xpath之类的东西。@JohnBarça,我发现xpath更容易理解maintain@Luis,谢谢,我很快会试试的。我需要快速解析千兆字节的XML,在短时间内了解非常优秀的xmltree库的各种复杂之处非常有趣。