I have a file xml as this:
<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>
I use for parsing this code:
- (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);
}
the result of nslog is:
feed:(
{
city = city;
people = 4004590;
},
{
width = 340;
height = 120;
},
{
temp = sunny;
people = "";
},
{ ///???? here there is an empty space
},
{
temp = cloudy;
people = "";
},
{
}
)
Now I don’t understand why there is a space between first dictionary of desc 1 and desc2, and I don’t know how “people” take the result of people1 and people2 in a single string
Can you help me?
You need to keep track of whether you are parsing the first occurrence of
descriptionwithin the data tag, or the second. This can easily be done with a boolean (if there are only two), or an integer (for multiple) that indicates which of the tags you are currently processing. Then, in theparser:didEndElement:method, you can assign the accumulated data to the correct dictionary based on the flag/counter.The other possibility, which I use in my XML parsing, is to accumulate characters for one tag at a time, then when I encounter the closing element for that tag, store the characters into the containing element’s Dictionary right then. In other words, when I encounter the endTag for
temp, I will immediately assign it to the currentdescriptiontag’s dictionary. Then, when I encounter the ending tag for thedescriptiontag itself, I can close out that dictionary, set the flag/increment the counter, and continue on with the next tag that is to be parsed.