使用wonderxml将XML转换为iPhone的对象

时间:2011-03-15 11:11:33

标签: xml xml-serialization nsxmlparser iphone

嘿所有! 我正在尝试使用wonderxml(http://code.google.com/p/wonderxml/)将我的xml转换为objective-c对象。 它适用于下面的简单案例...... XML:

<Defn>
   <name>Test1</name>
   <add>my address</add>
</Defn>

对应的类接口:

#import <Foundation/Foundation.h>
@interface Defn: NSObject {
    NSString *name;
    NSString *add;
 }
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *add;

@end

但是,如果我有如下所示的XML结构,我该怎么办?

   <Defn>
      <contact>
        <name>Test1</name>
        <add>my address</add>
      </contact>
      <contact>
        <name>Test1</name>
        <add>my address</add>
      </contact>
      .
      .
   </Defn>

我的班级界面应该是什么?

4 个答案:

答案 0 :(得分:1)

在你的第一个例子中,XML文件来自具有键的Defn保持字符串,你的ObjC示例遵循这个模式,带有一个名为Defn的对象,它包含2个字符串。

对于你的第二个例子,你有联系人持有字符串然后在Defn中有多个联系人,你可能想要使用类似的模式。除非您的Defn类重命名为contacts,然后是新的Defn类,其中包含一个联系对象数组。 所以我的实现将是。

contact.h

#import <Foundation/Foundation.h>
@interface contact: NSObject {
    NSString *name;
    NSString *add;
 }
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *add;
@end

Defn.h

#import <Foundation/Foundation.h>
@interface Defn: NSObject {
    NSMutableArray *contacts;
 }
@property (assign) NSMutableArray * contacts;
@end

这可能不是最好的解决方案,但它遵循XML结构,并且是原始Class接口示例的逻辑步骤。

答案 1 :(得分:0)

根据模型的复杂程度(在您的情况下 - 太基本也可能只使用GData),我的解决方案的里程数会有所不同。

但您可以将WonderXML与其祖先GDataXMLDocument混合使用。 (尚未测试下面的代码)

// NSMutableArray *contacts = [[NSMutableArray alloc]initWithCapacity:0];

- (void) parseXMLString:(NSString *)xmlString {
    XmlParser *parser = [[[XmlParser alloc] init] autorelease];
    NSData *xmlData = [xmlString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *xmlError;

    GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&xmlError];
    if (xmlDocument == nil) { 
        NSLog(@" Error parsing the XML Document");
        return; 
    }
    NSArray *contactElements = [[xmlDocument rootElement] elementsForName:@"Defn"];

    for (GDataXMLElement *contactElement in contactElements) {
        NSString  *contactString = [[[[contactElement attributes] objectAtIndex:0] stringValue];
        Contact *contact = [[[Contact alloc] init] autorelease];
        NSMutableArray *contactArray = [parser fromXml:contactString withObject:contact];
        // this should be one object in an array
        [contacts addObject:[contactArray objectAtIndex:0]];
    }
}

答案 2 :(得分:0)

我对XmlParser解析器类进行了更新,以便您可以传入一个对象数组和您正在寻找的xml。对指定的文件进行以下添加,您将能够完成所需的内容:

XmlParser.h

-(NSString *)arrayToXml:(NSArray *)objects andTag:(NSString *)tag inNameSpace:(NSString *)nameSpace;

XmlParser.m

- (void)addArray:(NSArray *)objects toParentElement:(GDataXMLElement *)parent
{
    for (id object in objects) {

        const char *objectName = class_getName([object class]);

        NSString *objectNameStr = [[NSString alloc] initWithBytes:objectName length:strlen(objectName) encoding:NSASCIIStringEncoding];

        GDataXMLElement * objectElement = [GDataXMLNode elementWithName:objectNameStr];

        NSMutableDictionary * propertyDic = [XmlParser propertDictionary:object];

        NSString *nodeValue = [NSString stringWithFormat:@"%@",@""];

        for (NSString *key in propertyDic) {

            if ([object valueForKey:key] != nil) {

                if ([[object valueForKey:key] isKindOfClass:[NSSet class]]) {

                    GDataXMLElement * parentElement = [GDataXMLNode elementWithName:key];
                    [self addSet:[object valueForKey:key] toParentElement:parentElement];
                    [objectElement addChild:parentElement];

                } else {

                    if ([[propertyDic objectForKey:key] isEqualToString:@"l"]) {

                        nodeValue = [NSString stringWithFormat:@"%llu",[[object valueForKey:key] unsignedLongLongValue]];

                    } else if ([[propertyDic objectForKey:key] isEqualToString:@"i"]) {

                        nodeValue = [NSString stringWithFormat:@"%d",[object valueForKey:key]];

                    } else {

                        nodeValue = [NSString stringWithFormat:@"%@",[object valueForKey:key]];
                    }

                    GDataXMLElement * childElement = [GDataXMLNode elementWithName:key stringValue:nodeValue];
                    [objectElement addChild:childElement];
                }
            }
        }

        [parent addChild:objectElement];

        [objectNameStr release];
    }
}

//convert object to xml string, you could modify the type maping to fit your requirement, 
//the reperesentation of type could be found in objective-c runtime reference.
-(NSString *)arrayToXml:(NSArray *)objects andTag:(NSString *)tag inNameSpace:(NSString *)nameSpace
{
    GDataXMLElement *parent = [GDataXMLNode elementWithName:tag];
    [parent addNamespace:[GDataXMLNode namespaceWithName:nil stringValue:nameSpace]];

    [self addSet:objects toParentElement:parent];

    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithRootElement:parent];

    NSData *xmlData = document.XMLData;

    NSString *xmlString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];

    NSString *bodyString = [xmlString substringFromIndex:21];

    NSString *headerString = [XmlHeaderHelper generateXmlHeader:tag and:nameSpace];

    xmlString = [NSString stringWithFormat:@"%@%@", headerString, bodyString];

    [document release];

    return xmlString;
}

因此,您将进行以下调用传递对象数组:

NSArray *contacts = [NSArray arrayFromObjects: contact1, contact2, nil];
[parser arrayToXml:contacts andTag:@"Defn" inNameSpace:@"http://mycontacts.com"]

答案 3 :(得分:-1)

有许多xml解析器,我使用xpathquery for iphone,我发现它更容易使用,请按照http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html希望这有帮助。