IOS:具有多个节点的NSMXLParser

时间:2012-04-01 20:45:21

标签: ios xcode nsxmlparser feed

我有一个文件xml:

<data>
    <first>
        <city>
            city
        </city>
        <people>
            400
        </people>
    </first>
    <size>
        <width>
            340
        </width>
        <height>
            120
        </height>
    </size>
    <description>
        <temp>
            sunny
        </temp>
        <people>
            45
        </people>
    </description>
    <description>
        <temp>
            cloudy
        </temp>
        <people>
                90
        </people>
    </description>

我用来解析这段代码:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{            

    currentElement = [elementName copy];
    if ([elementName isEqualToString:@"first"]) {
        firstType = [[NSMutableDictionary alloc] init];
        currentCity = [[NSMutableString alloc] init];
        currentPeople = [[NSMutableString alloc] init];
    }

    if ([elementName isEqualToString:@"size"]){
        currentSize = [[NSMutableDictionary alloc] init];
        width = [[NSMutableString alloc]init];
        height = [[NSMutableString alloc]init];
    }

    if ([elementName isEqualToString:@"description"]){
        desc1 = [[NSMutableDictionary alloc] init];
        temp1 = [[NSMutableString alloc]init];
        people1 = [[NSMutableString alloc]init];
    }

    if ([elementName isEqualToString:@"description"]){
        desc2 = [[NSMutableDictionary alloc] init];
        temp2 = [[NSMutableString alloc]init];
        people2 = [[NSMutableString alloc]init];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     

    if ([elementName isEqualToString:@"first"]) {

        [firstType setObject:currentType forKey:@"city"];
        [firstType setObject:currentQuery forKey:@"people"];
                [feed addObject:[firstType copy]];
    }
    if ([elementName isEqualToString:@"size"]){

        [currentSize setObject:tempC forKey:@"width"];
        [currentSize setObject:tempF forKey:@"height"];
        [feed addObject:[currentSize copy]];
    }
    if ([elementName isEqualToString:@"description"]){

        [desc1 setObject:temp1 forKey:@"temp1"];
        [desc1 setObject:people1 forKey:@"people1"];
        [feed addObject:[desc1 copy]];
    }

    if ([elementName isEqualToString:@"description"]){

        [desc2 setObject:temp1 forKey:@"temp2"];
        [desc2 setObject:people1 forKey:@"people2"];
        [feed addObject:[desc2 copy]];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    NSLog(@"found");
    if ([currentElement isEqualToString:@"city"]){
        [currentCity appendString:string];
    } 
    else if ([currentElement isEqualToString:@"people"]) {
        [currentPeople appendString:string];
    } 
    else if ([currentElement isEqualToString:@"width"]){
        [width appendString:string];
    }
    else if ([currentElement isEqualToString:@"height"]){
        [height appendString:string];
    }
    else if ([currentElement isEqualToString:@"temp"]){
        [temp1 appendString:string];
    }
    else if ([currentElement isEqualToString:@"temp"]){
        [temp2 appendString:string];
    }
    else if ([currentElement isEqualToString:@"people"]){
        [people1 appendString:string];
    }
    else if ([currentElement isEqualToString:@"people"]){
        [people2 appendString:string];
    }

}

- (void) parserDidEndDocument:(NSXMLParser *)parser {

    NSLog(@"feed:%@",feed);
}

nslog的结果是:

feed:(
        {
        city = city;
        people = 4004590;
    },
        {
        width = 340;
        height = 120;
    },
        {
        temp = sunny;
        people = "";
    },
        { ///???? here there is an empty space
    },
        {
        temp = cloudy;
        people = "";
    },
        {
    }
)

现在我不明白为什么desc 1和desc2的第一个字典之间有空格,我不知道“人”如何将people1和people2的结果用在单个字符串中

你能帮助我吗?

2 个答案:

答案 0 :(得分:2)

我猜你的问题是重复的代码块,例如:

else if ([currentElement isEqualToString:@"temp"]){
    [temp1 appendString:string];
}
else if ([currentElement isEqualToString:@"temp"]){
    [temp2 appendString:string];
}

在这种情况下,您的第一部分代码将执行两次,第二部分将永远执行。

还要检查代码的其他部分,你有几个问题。

答案 1 :(得分:0)

您需要跟踪是否正在解析数据标记中第一次出现description或第二次出现parser:didEndElement:。这可以通过布尔值(如果只有两个)或整数(对于多个)轻松完成,指示您当前正在处理哪些标记。然后,在temp方法中,您可以根据标记/计数器将累积的数据分配给正确的字典。

我在XML解析中使用的另一种可能性是一次为一个标记累积字符,然后当我遇到该标记的结束元素时,将字符存储到包含元素的Dictionary中。换句话说,当我遇到description的endTag时,我会立即将它分配给当前description标签的字典。然后,当我遇到- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { // ... SNIP ... if ( [ elementName isEqualToString:@"description" ] ) { curDescription = [ [ NSMutableDictionary alloc ] init ] ; } // ... SNIP ... accumulatedCharacters = [ [ NSMutableString alloc ] init ] } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { // ... SNIP ... if ( [ elementName isEqualToString:@"temp" ] ) { [ curDescription setValue:accumulatedCharacters forKey:@"temp" ] ; } if ( [ elementName isEqualToString:@"description" ] ) { // Save the curDescription object, then clear it for reuse on the next // occurrence of the tag [ curDescription release ] ; curDescription = nil ; } // ... SNIP ... [ accumulatedCharacters release ] ; accumulatedCharacters = nil ; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ { [ accumulatedCharacters appendString:string ] ; } 标签本身的结束标签时,我可以关闭该字典,设置标志/递增计数器,然后继续使用下一个要解析的标签。

{{1}}