NSXMLParser and Button Labels

Discussion in 'iOS Programming' started by DSchwartz88, Sep 21, 2008.

  1. DSchwartz88 macrumors 6502

    Joined:
    May 18, 2006
    #1
    Hey All,

    Im writing an application in which i need to grab data from an xml file (which i get by sending data to a url). Just so everyone gets it ill describe my process:

    1. I get the location of the user (for this experiment, im using a static URL, in the real deal i would be using lat and long i get from my location manager)

    2. I input my formatted URL into a string, using
    Code:
    NSString *string = @"myurl";
    3. I then init my url using the string i just made using
    Code:
    NSURL *url = [NSURL URLWithString:string];
    4. I then init my XMLParser using
    Code:
    locationFeed = [[[iPhoneLocation alloc] initWithURL:url] retain];
    4b. This the XML i get back (or should be getting back from the URL Request)

    Code:
    −<geonames>
       −<geoname>
         <name>Laguna Woods</name>
         <lat>33.6103009</lat>
         <lng>-117.7253305</lng>
         <geonameId>5364369</geonameId>
         <countryCode>US</countryCode>
         <countryName>United States</countryName>
         <fcl>P</fcl>
         <fcode>PPL</fcode>
         <distance>0.8177</distance>
       −</geoname>
    −</geonames>
    5. That then goes to the XML Parser i made which im attaching so people can actually help

    Code:
    - (iPhoneLocation*) initWithURL:(NSURL*)url
    {
    	NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    	[parser setDelegate:self];
    	
    	items = [[NSMutableArray alloc] init];
    	
    	currentProperty = nil;
    	curItem = nil;
    	curCategory = nil;
    	
    	[parser parse];
    	return self;
    }
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    	
    	if([elementName isEqualToString:@"geonames"]) {
    		curItem = [[NSMutableDictionary alloc] init];
    	}
    	
    	
    	else if(curItem != nil) {
    		currentProperty = [[[NSString alloc] initWithString:elementName] retain];
    	}
    	
    }
    
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    	if(curItem != nil && [elementName isEqualToString:@"geonames"]) {
    		[items addObject:curItem];
    		[curItem release];
    		curItem = nil;
    	}
    }
    
    
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    	
    	if(curItem != nil && currentProperty != nil) {
    		[curItem setObject:string forKey:currentProperty];
    		[currentProperty release];
    		currentProperty = nil;
    	}
    	
    }
    
    - (NSArray*)items {
    	return items;
    }
    6. I then try to print the name i get out of my xml file into a labels text field using
    Code:
    myLocationLabel.text = [[[locationFeed items] objectAtIndex:1] objectForKey:@"name"];
    (where name is the entity within the XML file that houses my location name)

    Using the debugger my breakdown right now is occurring when the parser goes through the didStartElement function in number 5. The

    Any help would be appreciated,

    ive posted alot of my code on here, and while im not a senior "amazing" developer I would like to ask that my code be used only for educational purposes and even though my code is pretty generic dont copy and paste for your own gain, your only hurting yourself by not learning how to code.

    Thats my little disclaimer, any help would be awesome, thanks again, if you need any other part of my code please tell me and im sure i can work something out.

    Thanks,
    Daniel
     
  2. grimjim macrumors member

    Joined:
    May 24, 2003
    #2
    So, Daniel, we meet again :D

    OK, I think that the problem here is that you haven't quite understood how NSXMLParser works. I'm afraid that it needs a bit more work than you've put in here. It's not like NSXMLDocument, which can read the contents of a file into memory and let you pick through it. NSXMLParser requires you to handle each element (each tag) separately.

    So, you've got it to look for the <geonames> tag, which is a good start, but you seem to be assuming that it will read the contents of that element into memory in a nice, structured form until it hits the </geonames> tag. 'Fraid not. What you're doing is making an object that contains just whatever happens to be between the start and end tags for geonames. Then you're asking for the object referred to by the key "name". As far as your app is concerned, there's no such key: it cannot deduce from the stuff you've given it that there is such a thing as "name".

    What you need to do is to handle explicitly all the tags that you want to work with. You've made a good start by creating (I assume) an NSMutableDictionary to hold the contents of each <geonames> element. What you now need to do is, once you have created your geonames object, listen out for each tag (<geoname>, then <name>, then <lat>, and so on), and add their contents to your object. Just to throw a further spanner in the works, I'm assuming that each <geonames> element can contain multiple <geoname> elements, so you will need to be able to handle that also: what happens if you get more than one <geoname> in your XML?

    The good news is that you can handle each element using the same methods that you're already using. All you need to do is to do different things on finding different element names.

    I hope that makes sense. I found that the SeismicXML sample code was really helpful when I was looking into this stuff.
     

Share This Page