2014-03-28 1 views
1

좀 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: 
    date=departedmember[0].findall('{http://www.ordnancesurvey.co.uk/xml/namespaces/osgb}deletionDate')[0].text 
except: 
    pass 

이 작동하지만이 같은 패스/제외하고 사용하기 싫어, 그래서이 있는지 궁금를 알려준 이와 같은 문서를 파싱하는 더 좋은 방법은 일부 요소가 선택적이라는 것입니다.

답변

4

. 게다가 try/except 블록을 피하려면 3 항을 사용할 수 있습니다.

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 
2

예, 문제는 검색 방법이 아니며 반환하는 요소가없는 경우 해당 참조를 참조하는 것입니다. 이 같은 코드를 작성할 수 있습니다 만 findall의 첫 번째 요소에 관심이 있기 때문에, 당신은 find(x)findall(x)[0]을 대체 할 수

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 
+0

이것은 try/except보다 확실히 깨끗합니다. 나는 이것이 xmltree 내에서 xpath와 같은 것을 사용해야한다면 큰 xml 문서를 파싱하는 가장 좋은 방법인지, 아니면 궁금해했다. –

+1

@ JohnBarça, 유지하기가 더 쉬운 xpath를 찾았습니다. – Luis

+0

@ 루이스, 언젠가 곧 해보겠습니다. 나는 XML의 기가 바이트를 서둘러 파싱하고 짧은 시간 프레임에서 매우 우수한 xmltree 라이브러리의 다양한 복잡성에 대해 머리를 쓰는 것이 재미있었습니다. –