views:

145

answers:

1

Hi. I use an instance of NSXMLParser. I store found chars in NSMutableStrings that are stored in an NSMutableDictionary and these Dicts are then added to an NSMutableArray.

When I test this everything seems normal: I count 1 array, x dictionnaries and x strings.

In a detailview controller file I want to show my parsed results. I call the class where everthing is stored but I get (null) returned.

This is what I do (wrong):

xAppDelegate.h

@interface xAppDelegate : NSObject <UIApplicationDelegate> {    
    UIWindow *window;
    UINavigationController *navigationController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

xAppDelegate.m

#import "xAppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"

@implementation xAppDelegate
@synthesize window, navigationController;

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

    // OFFLINE DOCUMENT > Resources folder
    NSString *Path = [[NSBundle mainBundle] bundlePath];
    NSString *DataPath = [Path stringByAppendingPathComponent:@"file.xml"];
    NSData *Data = [[NSData alloc] initWithContentsOfFile:DataPath];

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:Data];       

    XMLParser *parser = [[XMLParser alloc] initXMLParser];

    [xmlParser setDelegate:parser]; 
    [xmlParser setShouldProcessNamespaces:NO];
    [xmlParser setShouldReportNamespacePrefixes:NO];
    [xmlParser setShouldResolveExternalEntities:NO];

    [xmlParser parse];      

    [window addSubview: navigationController.view];
    [window makeKeyAndVisible];
}

- (void)dealloc {
    [window release];
    [navigationController release];
    [super dealloc];
}
@end

    XMLParser.h
@class xAppDelegate;

    @interface XMLParser : NSObject {
        NSMutableArray *array;
        NSMUtableDictionary *dictionary;
        NSSMutabletring *element;
xAppDelegate *appDelegate;
    }
- (XMLParser *) initXMLParser;
    @property (nonatomic, retain) NSMutableArray *array;
    @property (nonatomic, retain) NSMutableDictionary *dictionary;
    @property (nonatomic, retain) NSMutableString *element;


    XMLParser.m
#import "xAppDelegate.h"
#import "XMLParser.h"

    @synthesize array, dictionary, element;
- (XMLParser *) initXMLParser { 
[super init];
appDelegate = (xAppDelegate *)[[UIApplication sharedApplication] delegate];

return self;    
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {  
    array = [[NSMutableArray alloc] init];
        dictionary = [[NSMutableDictionary alloc] init];
}

    - (void)parser:(NSXMLParser *)parser 
didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName 
    attributes:(NSDictionary *)attributeDict
{
    ele = [elementName copy];
    if ([elementName isEqualToString:@"CONTAINER"]) {
        element = [[NSMutableString alloc] init];
    }
}
- (void)parser:(NSXMLParser *)parser
foundCharacters:(NSMutableString *)string
{   
    if ([ele isEqualToString:@"ELEMENTNAME"]) {
        [element appendString:string];
    }
}
- (void)parser:(NSXMLParser *)parser
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"CONTAINER"]) {
        [dictionary setObject:element forKey:@"ELEMENTNAME"];
        [array addObject:[dictionary copy]];
        }
}
- (void) dealloc {  
[element release];
[dictionary release];
[array release];
}

In my controller file I do this:

controller.h
@class XMLParser;

@interface controller : UIViewController {
 XMLParser *aXMLParser;
}

@property (nonatomic, retain) XMLParser *aXMLParser;

controller.m
#import "XMLParser.h"

@synthesize aXMLParser;

- (void)viewDidLoad {
    NSLog(@"test array: %@", aXMLParser.array);
    NSLog(@"test dict: %@", aXMLParser.dictionary);
    NSLog(@"test element: %@", aXMLParser.element);
}

When I test the value of my array, a dict or an element in the XMLParser.h file I get my result. What am I doing wrong so I can't call my results in my controller file? Any help is welcome, because I'm pretty stuck right now :/

A: 

You probably haven't initialised the NSMutableString element, so you are probably sending messages to a nil object.

That's a guess because you haven't posted the important code. We need to see

  • where you initialise the three objects
  • where you assign them e.g. you might be assigning nil to one of them without realising it.

Edited following latest bit of code

There's quite a lot wrong with the code, for instance, it leaks a lot of objects, but I can't see anything that would cause your specific issue, unless the the ELEMENTNAME elements don't appear inside the CONTAINER elements in your XML.

I'm not an expert on user interface code on iPhone, but are you sure applicationDidFinishLaunching runs before viewDidLoad?

Also, you don't seem to ever assign your parser to the aXMLParser property.

Some of the Other Issues

Your NSXMLParser leaks because you don't release it.

Your own parser also leaks for the same reason (you probably just want to use aXMLParser, not a locally defined one).

Your initXMPLarser method should look like:

- (XMLParser *) initXMLParser { 
    self = [super init];
    if (self != nil)
    {
        appDelegate = (xAppDelegate *)[[UIApplication sharedApplication] delegate];
    }

    return self;    
}

i.e. don't throw away the result of [super init] and make sure it is not nil.

array is allocated every time you hit a new element. Each tilme you hit a new element, you throw away and leak the previous array from the last element.

dictionary is allocated every time you hit a CONTAINER element. You should at least release the old one before allocating the new one.

element also leaks.

The copy of dictionary you put into the array also leaks. Objective-C collections retain their elements.

JeremyP
If one of the strings get nil assigned, nothing will work?I have alot of whitespaces and new lines etc, but doesn't the foundIgnorableWhitespace function automatic take care of that?Thx for your answer
FFXIII
@FFXIII: can you edit your question to include that new code? It'll make the formatting clearer. I'm not sure about foundIgnorableWhateSpace: Not all while space in an element is ignorable.
JeremyP
So where are you actually invoking a parse operation with your XML parser?
JeremyP
Updated the code a bit.
FFXIII
FFXIII
You release a copy of a dictionary in the same way as a dictionary. In your code, it would be appropriate to do this: `[array addObject:[[dictionary copy] autorelease]]`. I still don't see where you are setting aXMLParser
JeremyP