2011-03-10 93 views
0

我正试图使用​​TBXML解析XML文件。但是,这个解析器没有内置错误检查,所以如果一个元素不存在,它会崩溃。下面是我如何解析我的一个XML文件:更好的方法来检查是否有零?

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; 
} 

正如您所看到的,它会为每个项目调用两次。这对我来说似乎是一个巨大的浪费。任何方式我都可以对每件物品进行相同的验证,而无需做我现在正在做的事情?

回答

1

这里有一个较短的版本:

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; 
} 

使用枚举更新版本:

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的回答使得代码更短,但不应该影响运行时性能(枚举器实际上会增加一点开销);我的回答会让它跑得更快。但是除非这段代码经常被称为_extremely_,否则我怀疑你会看到任何实际的性能改进。 –

+0

工作得很好,谢谢! –

相关问题