2012-06-27 52 views
0

我想使用RestKit解析SOAP响应。如果我自己定义映射和关系,我能够成功地将SOAP XML响应转换为对象。但是,我想知道是否可以使用自省(或其他)来自动将SOAP XML响应转换为Objective-C对象。使用introspection restkit的对象映射

示例XML:

<return> 
    <userId xsi:type="xsd:int">1113050187</userId> 
    <location xsi:type="ns1:Location"> 
     <city xsi:type="xsd:string">San Francisco</city> 
     <state xsi:type="xsd:string">California</state> 
    </location> 
</return> 

我想这个XML转换成该对象:

@interface Return : NSObject 

@property (strong, nonatomic) NSInteger userId; // attribute 
@property (strong, nonatomic) Location *location; // relation 

@end 

我能想出用在返回类的自省来获取所有最接近的事属性和使用类似这样的每个属性: [映射addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@“userId.text”toKeyPath:@“userId”]];

而对于关系,我可以再次使用自省,找出我所有的类对象和使用mapRelationship:withMapping:在每一个

+0

你为什么不使用Sudzc?管道代码是自动生成的,你只需要提出请求并处理它。它也会创建所有相关的对象 – doNotCheckMyBlog

+0

我已经尝试过Sudzc,并且为我的wsdl生成了一些代码。我听说它适用于很多人,但在我的情况下它并没有! – pshah

+0

为什么没有?任何特定的错误?正在使用第三方wsdl?还是你自己的? – doNotCheckMyBlog

回答

0

我最终确立了性能递归映射到XML节点的方法,如果他们的名字比赛。该属性的命名约定和数据类型对此很重要。

在我发布之前,我已尽了最大的努力来清理它,但如果您需要任何帮助,请告诉我。

- (RKObjectMapping *)mapMe:(Class)class 
{ 
    RKObjectManager *objectManager = [RKObjectManager sharedManager]; 
    RKObjectMapping *mapping = [RKObjectMapping mappingForClass:class]; 
    id classType = objc_getClass([NSStringFromClass(class) UTF8String]); 
    unsigned int outCount, i; 
    objc_property_t *properties = class_copyPropertyList(classType, &outCount); 
    for (i = 0; i < outCount; i++) { 
     objc_property_t property = properties[i]; 
//  fprintf(stdout, "%s\n", property_getName(property)); 

     const char *type = property_getAttributes(property); 
     NSString *typeString = [NSString stringWithUTF8String:type]; 
     NSArray *attributes = [typeString componentsSeparatedByString:@","]; 
//  NSLog(@"attributes = %@", attributes); 
     NSString *typeAttribute = [attributes objectAtIndex:0]; 
//  NSLog(@"typeAttribute = %@", typeAttribute); 
     NSString *propertyType = [typeAttribute substringFromIndex:1]; 

     if ([propertyType hasPrefix:@"@"] && [propertyType length] > 1) { 
      NSString * typeClassName = [propertyType substringWithRange:NSMakeRange(2, [propertyType length]-3)]; //turns @"NSDate" into NSDate 
      Class typeClass = NSClassFromString(typeClassName); 
      if (typeClass != nil && ![typeClassName hasPrefix:@"NS"]) { 
//   my custom class detected. 
       RKObjectMapping *subMapping = [self mapMe:typeClass forObjectManager:objectManager]; 
       [mapping mapRelationship:[NSString stringWithUTF8String:property_getName(property)] withMapping:subMapping]; 
       [objectManager.mappingProvider setMapping:subMapping forKeyPath:[NSString stringWithUTF8String:property_getName(property)]]; 
      } else { 
       [mapping addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:[NSString stringWithFormat:@"%@.text", [NSString stringWithUTF8String:property_getName(property)]] toKeyPath:[NSString stringWithUTF8String:property_getName(property)]]]; 
      } 
     } 
    } 
    free(properties); 
    return mapping; 
} 

然后自动映射它称其为:

[self mapMe:[Myclass class]];