2011-03-10 12 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; 
} 

ご覧のとおり、各項目に対して2回コールしています。それは私には大きなオーバーヘッドの浪費のようです。私が今やっていることをすることなく、どのようにしても各項目の同じ検証を行うことができますか?列挙子を使用して

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

かなりうまくいきます、ありがとう! –

関連する問題