2011-03-10 5 views
0

TBXML을 사용하여 XML 파일을 구문 분석하려고합니다. 그러나이 파서에는 오류 검사가 내장되어 있지 않으므로 요소가 없으면 충돌이 발생합니다. XML 파일 중 하나를 파싱하는 방법은 다음과 같습니다.무언가가 nil인지 확인하는 더 나은 방법은 무엇입니까?

TBXML *XML = [[TBXML tbxmlWithXMLData:myxmlfile] retain]; 
if (XML.rootXMLElement) { 
    TBXMLElement *XMLRoot = XML.rootXMLElement; 
    if ([TBXML childElementNamed:@"blah" parentElement:XMLRoot]) { 
     TBXMLElement *Blah = [TBXML childElementNamed:@"blah" parentElement:XMLRoot]; 
     if ([TBXML childElementNamed:@"stuff" parentElement:Blah]) { 
      TBXMLElement *Item = [TBXML childElementNamed:@"item" parentElement:Blah; 
      if ([TBXML childElementNamed:@"stuff:blah" parentElement:Item]) { 
       TBXMLElement *something = [TBXML childElementNamed:@"stuff:blah" parentElement:Item]; 
       NSString *Something = [TBXML textForElement:something]; 
       //do something here... 
      } 
      else { 
       [self showFetchError]; 
       [XML release]; 
       return;} 
     } else { 
      [self showFetchError]; 
      [XML release]; 
      return;} 
    } else { 
     [self showFetchError]; 
     [XML release]; 
     return;} 
} else { 
    [self showFetchError]; 
    [XML release]; 
    return; 
} 

위에서 보듯이 각 항목에 대해 두 번 전화를 겁니다. 그것은 저에게 오버 헤드의 거대한 낭비처럼 보입니다. 어떤 방식 으로든 지금 당장하고있는 일을 수행하지 않고도 각 항목에 대해 동일한 검증을 수행 할 수 있습니까? 열거를 사용

BOOL success = NO; 
TBXML *XML = [[TBXML tbxmlWithXMLData:myxmlfile] retain]; 
if (XML.rootXMLElement) { 
    TBXMLElement *XMLRoot = XML.rootXMLElement; 
    if ([TBXML childElementNamed:@"blah" parentElement:XMLRoot]) { 
     TBXMLElement *Blah = [TBXML childElementNamed:@"blah" parentElement:XMLRoot]; 
     if ([TBXML childElementNamed:@"stuff" parentElement:Blah]) { 
      TBXMLElement *Item = [TBXML childElementNamed:@"item" parentElement:Blah; 
      if ([TBXML childElementNamed:@"stuff:blah" parentElement:Item]) { 
       success = YES; 
       TBXMLElement *something = [TBXML childElementNamed:@"stuff:blah" parentElement:Item]; 
       NSString *Something = [TBXML textForElement:something]; 
       //do something here... 
      } 
     } 
    } 
} 

if (!success) { 
    [self showFetchError]; 
    [XML release]; 
    return; 
} 

업데이트 버전 :

답변

1

여기에 짧은 버전의

TBXML *XML = [[TBXML tbxmlWithXMLData:myxmlfile] retain]; 
NSArray *path = [NSArray arrayWithObjects:@"blah", @"item", @"stuff:blah", nil]; 
NSEnumerator *e = [path objectEnumerator]; 
TBXMLElement *currentNode = XML.rootXMLElement; 
BOOL success = NO; 
while ((NSString *node = [e nextObject]) && currentNode) { 
    if ([node isEqualToString:[path lastObject]]) { 
     success = YES; 
     NSString *Something = [TBXML textForElement:currentNode]; 
     // do the last element thing with string 
    } else { 
     currentNode = [TBXML childElementNamed:node parentElement:currentNode]; 
    } 
} 

if (!success) { 
    [self showFetchError]; 
    [XML release]; 
    return; 
} 

열거 버전이 작동하는지 잘 모르겠어요,하지만 내 머리 위에 떨어져 당신의 문제를 해결해야한다.

+0

음을. –

+0

다른 해결책으로 내 대답을 업데이트했습니다. – Eimantas

+0

이 솔루션으로 인해 많은 업데이트가 급하게 이루어졌습니다. 이제 컴파일해야합니다! – Eimantas

1

당신은 같은 것들을 수행 할 수 있습니다 더 나은 보이지만 여전히 요소를 구문 분석 이중 통화의 문제가 해결되지

TBXMLElement *Blah = [TBXML childElementNamed:@"blah" parentElement:XMLRoot]; 
if (Blah) { 
    ... 
} 
+0

아, 그게 내가 찾고있는 것보다 많아. 나는 두 답을 모두 시도 할 것이고 빨리 작동하는 대답을 받아 들일 것입니다. :) –

+0

물론 두 기술을 결합 할 수 있습니다. Eimantas의 대답은 코드를 더 짧게 만들지 만 런타임 성능에는 영향을주지 않습니다 (열거자는 실제로 약간의 오버 헤드를 추가합니다). 내 대답은 더 빨리 달릴 것입니다. 그러나이 코드가 자주 호출되지 않으면 실제로 성능이 향상되지 않을지 의심 스럽습니다. –

+0

꽤 잘 작동합니다. 고마워요! –

관련 문제