用于NSXMLParser的数据类型

时间:2009-04-14 12:01:50

标签: iphone cocoa-touch nsxmlparser

我正在使用NSXMLParser来解析来自远程服务器的XML数据。我按照教程启动并运行,对于我正在创建的对象中的任何(NSString *)成员,一切正常。我还需要从XML数据中设置整数,例如:

<root>
    <child>
        <name> Hello </name>
        <number> 123 </number>
    </child>
    <child>
        <name> World</name>
        <number> 456 </number>
    </child>
</root>

在这种情况下,我将创建两个“子”对象。我正在使用:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    ...
    [aChild setValue:currentElementValue forKey:elementName];
    ...
}

委托设置值。这是我遇到问题的地方。每次都设置“NSString * name”成员,但是如果我使用NSInteger,那么每当我尝试设置“number”时,我都会得到一个EXC_BAD_ACCESS。所以我尝试使用“int”代替。但现在我无法使用键值编程,需要手动查找节点:

if([elementName isEqualToString:@"number"]) {
    aChild.number = [currentElementValue intValue]
}

这没关系,我可以解决这个问题,因为我知道我会得到什么节点,但它会变得更糟。当currentElementValue是根据教程的“NSMutableString *”时,即使字符串正确,它也不会返回正确的整数。例如:

    NSLog(@"NSMutableString Value: %@, and intValue %d\n", currentElementValue, [currentElementValue intValue]); 
// Value will be 123 but intValue will be 0

所以我使currentElementValue成为NSString而不是NSMutableString,我可以获得正确的intValue。但我在网上看到它是NSMutableString的原因是因为:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

代理用于设置值可以多次出现,但通常不会。所以我的问题是有人知道我做错了什么吗?对于NSXMLParser来说,这似乎是一个非常简单的案例,所以我确信这是我误解的事情。

3 个答案:

答案 0 :(得分:2)

我不知道你的代码在哪里失败,但这是处理这个问题的正确方法:

NSMutableString *buffer = [[NSMutableString alloc] init];

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    [buffer setString:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"number"]) {
        [aChild setNumber:[buffer intValue]];
        [buffer setString:@""];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [buffer appendString:string];
}

答案 1 :(得分:2)

  1. intValue的工作方式应相同NSStringNSMutableString。你确定Value是'123'而不是'\ n123'(\ n表示换行符号),如果字符串不是以十进制数字开头,那么intValue将返回0.

  2. 您是否在parser:didStartElement:正确清除了可变字符串?如果您只在parser:didEndElement:进行清洁,那么parser:foundCharacters:也会从父元素中收集字符。在这种情况下,将为您的字符串添加前缀,intValue将返回0。

  3. 你是正确的,因为parser:foundCharacters:可以为一个元素多次调用。

答案 2 :(得分:1)

在这里发生一些事情。

首先,您的XML字符数据中有明显的空白,例如

        <number> 456 </number>

你应该真正去除那个空白。这可能是导致[NSString intValue]的返回值出错的原因。如果你可以在源头删除它,那很好。如果没有,您可以通过执行以下操作将其剥离到接收端:

currentElementValue = [currentElementValue stringByTrimmingCharactersInSet:
    [NSCharacterSet whitespaceAndNewlineCharacterSet]];

您无法使用键/值的原因是您无法在NSMutableDictionary中存储NSInteger值。字典中的键和值都必须来自NSObject,而NSInteger(我猜测,这里)只是一个平台安全的typedef的int。所以你应该使用NSNumber:

NSNumber *theInt = [NSNumber numberWithInt:[currentElementValue intValue]];
[aChild setObject:theInt forKey:elementName];