Parser XML with NSXMLParser

Hey guys, I have an xml parsing question. Typically, the style of an XML file is as follows:

<person> <name> abc </name> <age> 19 </age> <gender> male </gender> </person> 

So we use

 elementName isEqualToString:@"name" elementName isEqualToString:@"age" elementName isEqualToString:@"gender" 

to identify the item.

Now I came across an xml file, for example:

 <person> <element type="name">abc</element> <element type="age">19</element> <element type="gender">male</element> </person> 

In this situation we cannot use

 elementName isEqualToString:@"name" 

So I tried to use

 if ([elementName isEqualToString:@"element"]) ο½› if ([[attributeDict objectForKey:@"type"] isEqualToString:@"name"){ ..... } } 

to identify the "name", but it did not give me any meaning, there is nothing if I tried to get the value of "name".

So, does anyone have any suggestions to fix this problem? thanks

PS: This is part of my code

 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ( [elementName isEqualToString:@"area"]) { if ([[attributeDict objectForKey:@"type"] isEqualToString:@"location"]) { NSString *description = [attributeDict objectForKey:@"description"]; NSArray *lineEntry = [[NSArray alloc] initWithObjects:description,nil ]; NSArray *lineKeys = [[NSArray alloc] initWithObjects:@"description",nil]; NSDictionary *dictItem = [[NSDictionary alloc] initWithObjects:lineEntry forKeys:lineKeys]; [lineKeys release]; [lineEntry release]; [dataLoad addObject:dictItem]; [dictItem release]; } } if ([elementName isEqualToString:@"forecast-period"]) { NSString *index = [attributeDict objectForKey:@"index"]; NSString *time = [attributeDict objectForKey:@"start-time-local"]; NSArray *indexEntry = [[NSArray alloc] initWithObjects:index,time,nil]; NSArray *indexKey = [[NSArray alloc] initWithObjects:@"index",@"start-time-local",nil]; NSDictionary *dicIndex = [[NSDictionary alloc] initWithObjects:indexEntry forKeys:indexKey]; [indexEntry release]; [indexKey release]; [weatherLoad addObject:dicIndex]; [dicIndex release]; } } 

it worked perfectly with these two parts, but it does not work if I try to get "predicted_code", "air_temperature_minimum", "air_temperature_maximum", "precis".

 <forecast-period index="1" start-time-local="2010-11-19T00:00:00+11:00" end-time-local="2010-11-20T00:00:00+11:00" start-time-utc="2010-11-18T13:00:00Z" end-time-utc="2010-11-19T13:00:00Z"> <element type="forecast_icon_code">1</element> <element type="air_temperature_minimum" units="Celsius">12</element> <element type="air_temperature_maximum" units="Celsius">24</element> <text type="precis">Sunny.</text> </forecast-period> 

Any suggestions? BTW, the whole xml file is here: ftp://ftp2.bom.gov.au/anon/gen/fwo/IDV10753.xml

+3
source share
2 answers

I assume that you want all the "elements" of the forecast period to be added to the same dictionary in which you put the index and the start time is local?

The original base if statement posted in the question is good, but the problem is that with NSXMLParser every xml tag ("forecast period", "element", "text", etc.) calls the didStartElement method.

Since there are several "forecast-period" tags and several "element" tags, your code will need to keep track of what the current parent tag / object is. After processing the "forecast period" tag, didStartElement starts again for the next "element" tag. In this call, the method parameters will have no indication that this "element" is a child of the "forecast period" with an "index" 1. Your code should track this.

Also, since the "element" tags have valid values ​​(for example, "Sunny" for type = precis), you will have to implement foundCharacters and didEndElement.

In didEndElement, depending on who the current target is, you have to put the data in the right place. If this is the end of the β€œforecast-period”, do nothing (it does not matter). If this is the end of the "element" tag, you should take the value captured by the characters found and add it to the last dictionary in weatherLoad. It also means that you need to switch to using NSMutableDictionary instead of NSDictionary.

The link you provided @itsaboutcode has a good example of all of the above (this is above the Attribute Handling section.

+2
source

Reading the section in the Attribute Handling section of Apple Event Driven XML Programming will give you a response.

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/XMLParsing/Articles/HandlingElements.html#//apple_ref/doc/uid/20002265-1001969

0
source

All Articles