Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Hello everybody,
I have tried some days now to write an app where I use the NSXMLParser. I have an URL and I am able to read from the source (it is an kml-file) and print the result using NSLog. I have tried to filter the items to be printed on the screen and that works fine as well. My problem is, that no matter how I try, the NSMutableArray I use to store the data is remaining empty. To make it a bit easier to understand my problem- here is some code:
The class creating an object car:

@implementation Car
@synthesize name;
@synthesize description;
@synthesize coordinates;
@synthesize point;

- (void) dealloc {
[description release];
[coordinates release];
[name release];
[point release];
[super dealloc];
}

@end


In the class XMLParser.m is the parser and the mutableArray defined:
#import "XMLParser.h"
#import "Car2GoAppDelegate.h"
#import "Car.h"

@implementation XMLParser
@synthesize theTestArrray;
@synthesize appDelegate;
@synthesize currentElementValue;
@synthesize aCar;

- (XMLParser *) initXMLParser {
[super init];
appDelegate = (Car2GoAppDelegate *) [[UIApplication sharedApplication]delegate];
return self;
}

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attribute:(NSDictionary *)attributeDict {
if([elementName isEqualToString:mad:"kml"]) {
appDelegate.cars = [[[NSMutableArray alloc]init]retain];
}
else if([elementName isEqualToString:mad:"Placemark"]) {

aCar = [[Car alloc]init];
}
else
return;
NSLog(@"In the didStartElement method: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *) string {
if(!currentElementValue) {
currentElementValue = [[NSMutableString alloc]initWithString:string];
}
else {
[currentElementValue appendString:string];
}
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *) elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:mad:"kml"])
return;
if([elementName isEqualToString:mad:"Style"])
return;
if([elementName isEqualToString:mad:"IconStyle"])
return;
if([elementName isEqualToString:mad:"Icon"])
return;
if([elementName isEqualToString:mad:"color"])
return;
if([elementName isEqualToString:mad:"colorMode"])
return;
if([elementName isEqualToString:mad:"scale"])
return;
if([elementName isEqualToString:mad:"href"])
return;
if([elementName isEqualToString:mad:"styleUrl"])
return;
if([elementName isEqualToString:mad:"a"])
return;

if([elementName isEqualToString:mad:"Placemark"]) {
[appDelegate.cars addObject:aCar];
[aCar release];
aCar = nil;
}

else {
[aCar setValue:currentElementValue forKey:elementName];
}
[currentElementValue release];
currentElementValue = nil;
}

- (void) dealloc {
[aCar release];
[currentElementValue release];
[super dealloc];
}

@end


The delegate for the whole app. I am using a rootviewcontroller containing and handling a flipsideview.

@implementation Car2GoAppDelegate

@synthesize window;
@synthesize rootViewController;
@synthesize cars;
@synthesize thisCar;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

NSString *URLToKml = [NSString stringWithFormat:mad:"%@", @"http:/d9t.de/nearest/kml"];
NSURL *url = [NSURL URLWithString:URLToKml];
NSXMLParser *xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc]initXMLParser];
[xmlParser setDelegate:parser];

BOOL success = [xmlParser parse];
if(success) {
NSLog(@"No errors");
NSInteger *test = [cars count];
NSLog(@"The number of elements in the array:%i", test);
}
else
NSLog(@"Error by parsing");

[window addSubview:[rootViewController view]];
[window makeKeyAndVisible];
}

- (void)dealloc {
[cars release];
[rootViewController release];
[window release];
[super dealloc];
}




I can compile the program without problems and I get the control output "No errors" indicating that the parsing is ok (see above). But I do not understand why the array cars with the data always remains empty??? Can anyone help me with this problem? I have followed the tutorial here to create my app...

Thanks in advance!
loop
 

namanhams

macrumors regular
Jun 3, 2009
153
0
My idea : i just read through the code i dont think it's hard to debug your code by using NSLog. Printing out wherever you add a car to your array may help.
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Hello and thanks for your answers!
@robbieduncan: I am not sure I understand what you mean? Do you mean in the kml/xml file? If so - I do not have any influence on how it is created - I only read it. If you mena something in my code...could you give me an example on what I could change in the code? I am quite new to object-c making me abit confused about the syntax :-S

@namanhams: I have used NSLog to follow the flow in my code and it did indeed give me some hints. The problem is only that I can write the objects from the kml file out oin screen using NSLog. Only the array remains empty... I dont understand why??
I have retein the array and I have allocated it to. I have initiated it and everytime I reach a <Placemark> end tag I put the object car into the array. From the array I then read the object's parts like for instance:
Car *theFirstCar = [cars objectAtIndex:0];
NSLog(@"The first car's coordinates stored in the array:%@", theFirst.coordinates);


By writing the following code I intended to count the number of elements in the cars array, and the NSLog alway shows a count of 0...?:
NSInteger *test = [cars count];
NSLog(@"The number of elements in the array:%i", test);


So, I have no Idea why my array is not populated? Where in the code should I add objects to it? Am I thinking wrong about how tosave the objects? Am I missing some detail by creating the array or by creating the car objects. I have tested to print out a car object as well and did not get that to work eather:
(in the xmlParser.m)
else {
[aCar setValue:currentElementValue forKey:elementName];
NSLog(@"The description of the current car:%@",aCar.description);
}


Does anyone have any experience with xmlParser and any hint to help me solve this? I am sure that it is not very hard, because the parsing itself works fine and I can print out the items from the xml file without problems...

Thanks in advance!
/loop
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Hello and thanks for your answers!
@robbieduncan: I am not sure I understand what you mean? Do you mean in the kml/xml file? If so - I do not have any influence on how it is created - I only read it. If you mena something in my code...could you give me an example on what I could change in the code? I am quite new to object-c making me abit confused about the syntax :-S

No I mean posting code onto this website: it formats the code making it readable and turns of generation of :) characters.

Like this:

Code:
-(void) myMethod:(NSString *) myParam
{
}
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Ah, ok! Here comes the code in a more readable format:
Code:
@implementation Car
@synthesize name;
@synthesize description;
@synthesize coordinates;
@synthesize point;

- (void) dealloc {
[description release];
[coordinates release];
[name release];
[point release];
[super dealloc];
}

@end

In the class XMLParser.m is the parser and the mutableArray defined:
Code:
#import "XMLParser.h"
#import "Car2GoAppDelegate.h"
#import "Car.h"

@implementation XMLParser
@synthesize theTestArrray;
@synthesize appDelegate;
@synthesize currentElementValue;
@synthesize aCar;

- (XMLParser *) initXMLParser {
[super init];
appDelegate = (Car2GoAppDelegate *) [[UIApplication sharedApplication]delegate];
return self;
}

- (void) parserNSXMLParser *)parser didStartElementNSString *)elementName namespaceURINSString *)namespaceURI qualifiedNameNSString *)qualifiedName attributeNSDictionary *)attributeDict {
if([elementName isEqualToString:@"kml"]) {
appDelegate.cars = [[[NSMutableArray alloc]init]retain];
}
else if([elementName isEqualToString:@"Placemark"]) {

aCar = [[Car alloc]init];
}
else
return;
NSLog(@"In the didStartElement method: %@", elementName);
}

- (void)parserNSXMLParser *)parser foundCharactersNSString *) string {
if(!currentElementValue) {
currentElementValue = [[NSMutableString alloc]initWithString:string];
}
else {
[currentElementValue appendString:string];
}
}

- (void) parserNSXMLParser *)parser didEndElementNSString *) elementName namespaceURINSString *)namespaceURI qualifiedNameNSString *)qName {
if([elementName isEqualToString:@"kml"])
return;
if([elementName isEqualToString:@"Style"])
return;
if([elementName isEqualToString:@"IconStyle"])
return;
if([elementName isEqualToString:@"Icon"])
return;
if([elementName isEqualToString:@"color"])
return;
if([elementName isEqualToString:@"colorMode"])
return;
if([elementName isEqualToString:@"scale"])
return;
if([elementName isEqualToString:@"href"])
return;
if([elementName isEqualToString:@"styleUrl"])
return;
if([elementName isEqualToString:@"a"])
return;

if([elementName isEqualToString:@"Placemark"]) {
[appDelegate.cars addObject:aCar];
[aCar release];
aCar = nil;
}

else {
[aCar setValue:currentElementValue forKey:elementName];
}
[currentElementValue release];
currentElementValue = nil;
}

- (void) dealloc {
[aCar release];
[currentElementValue release];
[super dealloc];
}

@end

The delegate for the whole app. I am using a rootviewcontroller containing and handling a flipsideview.
Code:
@implementation Car2GoAppDelegate

@synthesize window;
@synthesize rootViewController;
@synthesize cars;
@synthesize thisCar;

- (void)applicationDidFinishLaunchingUIApplication *)application {

NSString *URLToKml = [NSString stringWithFormat:@"%@", @"http:/d9t.de/nearest/kml"];
NSURL *url = [NSURL URLWithString:URLToKml];
NSXMLParser *xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc]initXMLParser];
[xmlParser setDelegatearser];

BOOL success = [xmlParser parse];
if(success) {
NSLog(@"No errors");
NSInteger *test = [cars count];
NSLog(@"The number of elements in the array:%i", test);
}
else
NSLog(@"Error by parsing");

[window addSubview:[rootViewController view]];
[window makeKeyAndVisible];
}

- (void)dealloc {
[cars release];
[rootViewController release];
[window release];
[super dealloc];
}

Another question:
How does
Code:
[aCar setValue:currentElementValue forKey:elementName];
work?
I thought that I might have defined the key false and because of that does not the car object contain any data?

Another issue is, in the tutorial code was a part like:
Code:
//Extract the attribute here.
aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];
Because I do not have anything like an id or any attributes at all in the tags, i cannot define this part, can I?
Or shall I define it in an alternative way?
What is actually this attributeDict?

Thanks in advance!
/loop
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Hi again!
I suppose that at least one of my problems is in the following code:

Code:
else if([elementName isEqualToString:@"description"]) {
[aCar setValue:currentElementValue forKey:elementName];
NSLog(@"aCars description is:%@", aCar.description);

This is in the didEndElement method and my intention is to go to the element tagged with description and that part seems to work fine. After finding such a element I intend to take the value found and save it into the part of a Car object called description (it is a NSString). The last code row should, but DOES NOT, print out the value I assigned to the car object... it is always null.... no matter how I try...why?

Thanks in advance!
/loop
 

namanhams

macrumors regular
Jun 3, 2009
153
0
Hi MACloop,

In the XMLParser file, i think the bug is in the second method (... didStartElement...). May be the mutable array (cars) is not created yet, so it's still nill, or may be the car is not created yet. In objective C, message to nill object is allowed.
Hope this helps.
 

namanhams

macrumors regular
Jun 3, 2009
153
0
Sorry i haven't read your code yet, but since i just had the same problem minutes ago, and i found that it's because of the nill object, so i guess yours may be same.
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Hi MACloop,

In the XMLParser file, i think the bug is in the second method (... didStartElement...). May be the mutable array (cars) is not created yet, so it's still nill, or may be the car is not created yet. In objective C, message to nill object is allowed.
Hope this helps.
Thanks for your answer namanhams!
I am not sure I understand what you mean :eek: ...
I am creating an array to fill with objects if the parser read the tag <kml>. This tag only appears at the beginning of the file, indicating that we are beginning to read a new file. The car object is created when the tag <Placemark> is read, because a placemark includes all the data to be stored into the car object... This is how I reason...but it might of course be wrong...
What do you mean about the nil values? When I print the value out in the console using NSLog the value shown on the screen is (null)... hmmm... :confused:


/loop
 

namanhams

macrumors regular
Jun 3, 2009
153
0
Yes i meant "null" (i think null and nill are the same :cool:)

NSMutableArray *cars; // now car is still null
cars = [[NSMutableArray alloc] init]; // car is created, not null anymore.

For the method that i stated above, i see that only 1 of "cars" or "aCar" is created because they are put into if-else. That means, 1 of them is null.
That's the problem.
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
Yes i meant "null" (i think null and nill are the same :cool:)

NSMutableArray *cars; // now car is still null
cars = [[NSMutableArray alloc] init]; // car is created, not null anymore.

For the method that i stated above, i see that only 1 of "cars" or "aCar" is created because they are put into if-else. That means, 1 of them is null.
That's the problem.

Thanks again!
Yes nil and null are the same...I thought so too
I have initialized the array as you write above and after that I add objects to it...I do not understand why the array remains empty...? I think it would be helpful if you could perhapt give me an example...using my code...? Thanks in advance!
/loop
 

namanhams

macrumors regular
Jun 3, 2009
153
0
Thanks again!
Yes nil and null are the same...I thought so too
I have initialized the array as you write above and after that I add objects to it...I do not understand why the array remains empty...? I think it would be helpful if you could perhapt give me an example...using my code...? Thanks in advance!
/loop


In which part do you initialize the array ?
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
In which part do you initialize the array ?

I initialize the array when the parser encounters a <kml> tag in the following code:

Code:
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attribute:(NSDictionary *)attributeDict {	
	if([elementName isEqualToString:@"kml"]) {
		appDelegate.cars = [[NSMutableArray alloc]init];//a new file to read - an new array is created
	}
	else if([elementName isEqualToString:@"Placemark"]) {
		aCar = [[Car alloc]init];//initialize a new car object when a Placemark tag was found
	}
 

Vinprakash

macrumors newbie
Mar 13, 2009
3
0
The class creating an object car:
signature_Sign.jpg
:)
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
The class creating an object car:
signature_Sign.jpg
:)

The code for the class have I posted here above, but here it comes again:
Code:
@implementation Car
@synthesize name;
@synthesize description;
@synthesize coordinates;
@synthesize point;

- (void) dealloc {
[description release];
[coordinates release];
[name release];
[point release];
[super dealloc];
}

@end

Perhapt something is wrong with the object Car and the definition of it?
/loop
 

MACloop

macrumors 6502
Original poster
May 18, 2009
393
0
Germany
The tutorial I followed used the appDelegate.cars to point at the array? Is there something wrong with that? But if it was, the car object should hold some data anyway....hmmm :confused:
 

namanhams

macrumors regular
Jun 3, 2009
153
0
Code:
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attribute:(NSDictionary *)attributeDict {	
	if([elementName isEqualToString:@"kml"]) {
		appDelegate.cars = [[NSMutableArray alloc]init];//a new file to read - an new array is created
	}
	else if([elementName isEqualToString:@"Placemark"]) {
		aCar = [[Car alloc]init];//initialize a new car object when a Placemark tag was found
	}

Hi,

Do you try to print out the number of elements in "cars" everytime you insert a car ?
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
MACloop, can we see the interface (.h) file for your Car class? You seem to be trying to use it like an NSDictionary (as in, "[aCar setValue:currentElementValue forKey:elementName];") but I doubt that is how it is defined.

Also, nil and NULL are not the same thing and not interchangeable. nil is specific to Objective-C and has more powers than NULL.

Are you sure you have a good handle on the basics of Objective-C? Perhaps it is time to step back from the real coding and review those first before continuing.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.