2009-07-16 9 views
1

私は、libxml2を使って一般的なXMLをCore Dataパーサに書き込もうとしています。私は両方を制御できるので、XML要素はオブジェクトと属性に正確に対応し、オブジェクトのプロパティに対応します。 NSString以外のタイプの属性を除いて、これはすべて問題なく、すべて正常に動作します。私はセレクタが入力タイプについて何も知らないことを認識していますが、それを決定する他の方法はありますか?つまり、私は一般的に文字列をセレクタに必要な型に変換できますか、if-then-elseスイッチをどこかに書く必要がありますか?ここでセレクタの入力引数型を取得するにはどうすればよいですか?

は私の進行中のコードです:

static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, 
          int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes) { 
    //set up a local pool so we can release these objects 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    FormParser *parser = (FormParser *)ctx; 
    NSString *elementName = [[NSString alloc] initWithUTF8String:(const char *)localname]; 

    NSManagedObject *localObject = [parser.managedObjectContext insertNewObjectForEntityForName:elementName]; 

    // according to http://www.xmlsoft.org/html/libxml-SAX2.html#xmlSAX2StartElementNs, 
    // there are 5 parts to the attribute array: localname/prefix/URI/value/end 
    int attribCounter; 
    for (attribCounter = 0; attribCounter < (nb_attributes * 5); attribCounter++) 
    { 
     NSString *attributeValue = nil; 
     NSString *attributeName = [[NSString alloc] initWithUTF8String:(const char *)attributes[attribCounter]]; 

     //let's skip over the prefix 
     attribCounter++; 
     //and the URI 
     attribCounter++; 
     //and get to the value 
     attribCounter++; 
     //increment after using counter so we can get the end value 
     const char *valueStart = (const char *)attributes[attribCounter++]; 
     const char *valueEnd = (const char *)attributes[attribCounter]; 

     //if we have good values, init a value with 
     if (valueStart && valueEnd) { 
      attributeValue = [[NSString alloc] initWithBytes:attributes[attribCounter-1] length:(strlen(valueStart) - strlen(valueEnd)) encoding:NSUTF8StringEncoding]; 
     } 

     SEL setAttribute = NSSelectorFromString([NSString stringWithFormat:@"set%@:", [attributeName capitalizedString]]); 
     if (attributeValue && [localObject respondsToSelector:setAttribute]) 
     { 
      //HERE'S WHERE I NEED TO CHECK TYPE AND CAST IF NEEDED 
      [localObject setValue:attributeValue forKey:attributeName]; 
     } 

    } 

    //set parser's current object 
    SEL setCurrent = NSSelectorFromString([NSString stringWithFormat:@"setCurrent%@:", [elementName capitalizedString]]); 
    if ([parser respondsToSelector:setCurrent]) 
    { 
     [parser performSelector:setCurrent withObject:localObject]; 
    } 

    //set parent 
    SEL setParent = NSSelectorFromString(@"setParent"); 
    if ([localObject respondsToSelector:setParent]) 
    { 
     SEL getParent = NSSelectorFromString([NSString stringWithFormat:@"getCurrent%@", [[parser getElementParent:elementName] capitalizedString]]); 
     if ([parser respondsToSelector:getParent]) 
     { 
      [localObject performSelector:setParent withObject:[parser performSelector:getParent]]; 
     } 
    } 

    NSError *error = nil; 
    if (![parser.managedObjectContext save:&error]) 
    { 
     if (parser.delegate != nil && [parser.delegate respondsToSelector:@selector(parser:didFailWithError:)]) { 
      [parser.delegate parser:parser didFailWithError:error]; 
    } 
    } 
    [pool release]; 
} 

答えて

0

はグーグルで保ち、私はNSMethodSignatureを使用できることがわかった。

- (const char *)getArgumentTypeAtIndex:(NSUInteger)index 

ここrelevant documentationです。

それはこのエンコードは、実装固有のものであるため、アプリケーションは慎重にそれを使用する必要があり

を言うんが。

ETA:Aaand、私は行き止まりに戻ります。私が知ることができるのは、それがクラスだということだけです。もっと具体的な質問をします。

+0

最近、エンコードがかなり修正されています。 ''を参照してください。有効な選択肢はすべて行272で '_C'で始まります。 –

+0

ありがとう、Ben - great resource。このアプローチの私の問題は、すべてが '@'に戻ってくることでした。もちろん、これは_C_IDを意味し、私がこれをやろうとしていた方法では役に立たなかったのです。 – Don

関連する問題