Saving XML Parsed data to NSMutableDictionary Best Practice - iphone

This question might have been asked frequently but I have read almost all of them and yet couldn't figure out a solution for my case.
I plan to save the parsed data to a NSMutableDictionary. Parser works ok and If I get a log it shows all data parsed. the problem is the last Item only saves in the NSDictionary. I can guess that I placed the dictionary in a wrong method but I can't figure out a better solution for saving. I use dictionary in order to hold the name and the text of element. here is my code :
#implementation Parser
#synthesize currentElementPointer, rootElement;
#synthesize dictionary;
-(id)initParser
{
if(self = [super init]) {
tvc = (TimeTableViewController*)[[UIApplication sharedApplication]delegate];
APUAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
context = [appDelegate managedObjectContext];
[self deleteAllObjects:#"TimeTable"];
}
return self;
}
#pragma mark -
#pragma mark PARSER
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
self.parsing = YES;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"intake"])
{
NSString *name = attributeDict[#"name"];
self.parsing = [name isEqualToString:[self sendIntakeToParser]];
}
if(![self isParsing]) return;
if(self.rootElement == nil) {
self.rootElement = [[List alloc]init];
self.currentElementPointer = self.rootElement;
} else {
List *newList = [[List alloc]init];
newList.parent = self.currentElementPointer;
[self.currentElementPointer.subElements addObject:newList];
self.currentElementPointer = newList;
}
self.currentElementPointer.name = elementName;
self.currentElementPointer.attributes = attributeDict;
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(![self isParsing]) return;
if([self.currentElementPointer.text length] > 0) {
self.currentElementPointer.text = [self.currentElementPointer.text stringByAppendingString:string];
} else {
self.currentElementPointer.text = string;
}
dictionary = [[NSMutableDictionary alloc]init];
[dictionary setObject:[self.currentElementPointer text] forKey:[self.currentElementPointer name]];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([self isParsing])
{
self.currentElementPointer = self.currentElementPointer.parent;
} else if ([elementName isEqualToString:#"intake"])
{
self.parsing = YES;
}
}
This is my xml structure:

The source of your problem is that you re-instantiate your dictionary with each call to parser:foundCharacters: which will be called at least once per element that has text. One thing you could do is move the dictionary instantiation to parser:didStartElement:... whenever elementName is equal to #"timetable", instantiate a mutable array in parser:didStartDocument: and then, in parser:didEndElement:..., if the elementName is `#"timetable", add it to your array.
An example of this is shown below:
Parser.h:
#import <Foundation/Foundation.h>
#interface Parser : NSObject <NSXMLParserDelegate>
- (void)parseData:(NSData *)data;
#end
Parser.m:
#import "Parser.h"
#interface Parser ()
#property (nonatomic,strong) NSMutableArray *timetableDictionaries;
#property (nonatomic,strong) NSMutableDictionary *currentTimetableDictionary;
#property (nonatomic,copy) NSString *currentElementName;
#end
#implementation Parser
- (void)parseData:(NSData *)data
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
self.timetableDictionaries = [NSMutableArray array];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
self.currentElementName = elementName;
if ([elementName isEqualToString:#"timetable"]) {
self.currentTimetableDictionary = [NSMutableDictionary dictionary];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (self.currentElementName) {
NSString *existingCharacters = self.currentTimetableDictionary[self.currentElementName] ? : #"";
NSString *nextCharacters = [existingCharacters stringByAppendingString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
if ([nextCharacters length] > 0) {
self.currentTimetableDictionary[self.currentElementName] = nextCharacters;
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"timetable"]) {
[self.timetableDictionaries addObject:self.currentTimetableDictionary];
self.currentTimetableDictionary = nil;
}
self.currentElementName = nil;
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"timetable dictionaries = %#",self.timetableDictionaries);
}
#end
I tested the above class with the following file:
<weekof week="2013-07-29">
<intake name="APCF1304">
<timetable>
<date>SOME DATE</date>
<time>SOME TIME</time>
<lecturer>SOME LECTURER</lecturer>
</timetable>
<timetable>
<date>ANOTHER DATE</date>
<time>ANOTHER TIME</time>
<lecturer>ANOTHER LECTURER</lecturer>
</timetable>
</intake>
</weekof>
And it gave the following output:
2013-08-11 11:50:03.205 MyParser[25368:c07] timetable dictionaries = (
{
date = "SOME DATE";
lecturer = "SOME LECTURER";
time = "SOME TIME";
},
{
date = "ANOTHER DATE";
lecturer = "ANOTHER LECTURER";
time = "ANOTHER TIME";
}
)
However, you've built a tree of the document already, presumably for another purpose, so you could just re-use that at the end of your parsing to build your dictionaries. For example, if you just wanted dictionaries for each timetable, you could do something that looked like this, in pseudocode:
dictionaries = [new mutable array]
element = self.root
[extract dictionaries from: element to:dictionaries]
implementation of extractDictionariesFrom:element to:dictionaries:
if any subelement has non-nil text:
item = [new mutable dictionary]
for each sub element:
item[element name] = element text
[add item to dictionaries]
else
for each subelement:
[extract dictionaries from: subelement to: dictionaries]
Then you could discard the use of the mutable dictionary in your parser callback.

Related

How Can I process all elements in xml?

I have an xml like this, but my XMLParser jumps 1-2 elements, and not process it. I think it works fine, but it not. What do i wrong?
Here is the xml, and i'd like to get the all item tag, and it's child elements.
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>News</title>
<description>News - Android</description>
<link>http://www.p.com</link>
<item>
<title>World Bench Press highlights - Day 2</title>
<pubDate>Tue, 21 May 2013 00:00:00 +0000</pubDate>
<imgLink>http://www.powerlifting-ipf.com/typo3temp/pics/1b7ecb3ac3.jpg</imgLink>
<description>desc </description>
<URL> some URL </URL>
</item>
</channel>
</item>
</rss>
</channel>
Here is my XMLParser file, but i can't get any node, and it not put in my array. Not going to the
if ([elementname isEqualToString:#"item"])
#import <Foundation/Foundation.h>
#import "XMLParser.h"
#implementation XMLParser
#synthesize tweets = _tweets;
NSMutableString *currentNodeContent;
NSMutableString *copy;
NSXMLParser *parser;
Tweet *currentTweet;
bool isStatus=YES;
-(id) loadXMLByURL:(NSString *)urlString
{
_tweets = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
NSLog(#"0");
return self;
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"1");
NSLog(#"currentnode %#",currentNodeContent);
currentNodeContent = [[NSMutableString alloc] initWithCapacity:100];
[currentNodeContent appendString:string];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"2 Elementname : %#",elementname);
if ([elementname isEqualToString:#"item"])
{
currentTweet = [Tweet alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"title"])
{
NSLog(#"%#",currentNodeContent);
currentTweet.content = [NSString stringWithFormat:#"%# %#",currentTweet.content ,currentNodeContent];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"ELEMENT: %#",elementname);
if ([elementname isEqualToString:#"description"])
{
currentTweet.description = currentNodeContent;
}
if ([elementname isEqualToString:#"pubDate"])
{
currentTweet.dateCreated = currentNodeContent;
}
if ([elementname isEqualToString:#"title"])
{
currentTweet.title = currentNodeContent;
}
if ([elementname isEqualToString:#"imgLink"])
{
currentTweet.imgLink = currentNodeContent;
}
if ([elementname isEqualToString:#"URL"])
{
currentTweet.URL = currentNodeContent;
}
if ([elementname isEqualToString:#"item"])
{
NSLog(#"%# elem:",currentNodeContent);
[self.tweets addObject:currentTweet];
currentTweet = nil;
currentNodeContent = nil;
}
}
#end
Your approach is wrong because you are reallocating your mutable string every time that the XML parser finds new characters. This means that if you get a string like #"Hello", and the strings gets parsed into two separated string #"He" and #"llo", just #"llo" gets put into the mutable string. The correct approach is to allocate a new mutable string every time that you find a new tag, not when you find new characters.
Not sure because I am not aware of the whole context, but I would try to edit your first two methods this way:
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"1");
NSLog(#"currentnode %#",currentNodeContent);
[currentNodeContent appendString:string];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentNodeContent= [NSMutableString new];
NSLog(#"2 Elementname : %#",elementname);
if ([elementname isEqualToString:#"item"])
{
currentTweet = [Tweet alloc];
isStatus = YES;
}
}
Let me know what result you get. I also recommend putting breakpoints into every method to see (in the case) why you get some particular strings instead of expected results.
Edit
As for the XML, I tried to check it with xmllint, and it some errors. The problem is with these two extra lines after closing the channel tag:
</item> <!-- Not needed -->
</rss>
</channel> <!-- Not needed -->
You have one between and . Maybe that tag could be messing the parse procedure, try deleting it

Not getting data after XML Parser

I am using XML parser to get my data.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ( [elementName isEqualToString:#"country"] )
{
x++;
[messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:Id,#"ID",Name,#"NAME",Image,#"IMAGE",nil]];
//**111**
NSLog(#"Data in Message : %#", [messages objectAtIndex:(x-1)]);
[Id setString:#""];
[Name setString:#""];
[Image setString:#""];
}
if ( [elementName isEqualToString:#"id"] )
{
[Id appendString:currentNodeContent];
}
if ( [elementName isEqualToString:#"name"] )
{
[Name appendString:currentNodeContent];
}
if ( [elementName isEqualToString:#"im"] )
{
[Image appendString:currentNodeContent];
}
}
//At //*111* the message is printed but when I do this after calling the xml parser, it doesn't print:
chatParser = [[NSXMLParser alloc] initWithData:receivedData];
[chatParser setDelegate:self];
[chatParser parse];
NSLog(#"\n\nMessages...\n\n%#", messages); //here there is no data printing
at this point it is printing empty..
Messages.
(
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
{
ID = "";
IMAGE = "";
NAME = "";
},
)
I have define message properties and also sythesize it.
In viewDidLoad I have did this
messages=[[NSMutableArray alloc] init];
Thank you for help..
Your problem is that you use same objects Id, Name, Image all the time and with the lines
[Id setString:#""];
[Name setString:#""];
[Image setString:#""];
set their values to "" at the end of each country element.
It better should look like this (not tested, maybe some typos):
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"id"] )
{
[lastMessage setObject:currentNodeContent forKey:"ID"];
}
else if ( [elementName isEqualToString:#"name"] )
{
[lastMessage setObject:currentNodeContent forKey:"NAME"];
}
else if ( [elementName isEqualToString:#"im"] )
{
[lastMessage setObject:currentNodeContent forKey:"IMAGE"];
}
else if ( [elementName isEqualToString:#"country"] )
{
NSLog(#"Data in Message : %#", lastObject);
[messages addObject:lastMessage];
[lastMessage release];
}
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elName namespaceURI:(NSString *)uri
{
if ( [elementName isEqualToString:#"country"] )
{
lastMessage = [[NSMutableDictionary alloc]init];
}
}
Use the Below Code.Where Table is NSObject Class with the CaseId,PartyId,CartId as a properties in this class.If you have the xml url just called loadXMLByURL method with URl.After parsing you will get Each Object in TableArray which have the Table object with above properties.
NSMutableString *currentNodeContent;
NSXMLParser *parser;
Tweet *currentTweet;
bool isStatus;
-(id) loadXMLByURL:(NSString *)urlString
{
_tweets = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"Table"])
{
currentTable = [Table alloc];
isStatus = YES;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"CaseId"])
{
currentTable.CaseId = currentNodeContent;
}
if ([elementname isEqualToString:#"PartyId"])
{
currentTable.PartyId = currentNodeContent;
}
if ([elementname isEqualToString:#"CartId"])
{
currentTable.CartId = currentNodeContent;
}
}
if ([elementname isEqualToString:#"Table"])
{
[self.tableArray addObject:currentTable];
currentTable = nil;
currentNodeContent = nil;
}
}
Let me know if you have any doubt.

NSXMLParser divides strings containing foreign(unicode) characters

I have ran into a peculiar problem with NSXMLParser.
For some reason it cuts out all the characters in front of all the norwegian characters æ, ø and å.
However, the problem seems to be the same with all non a-z characters.(All foreign characters)
Examples:
Reality: Mål
Output: ål
Reality: Le chant des sirènes
Output: ènes
Heres an example from the log where I have printed out the string from:
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
Log:
2012-02-22 14:00:01.647 VotePlayClient[2776:207] found characters: Le chant des sir
2012-02-22 14:00:01.647 VotePlayClient[2776:207] found characters: ènes
You can clearly see that it jumps to a new line whenever it encounters a foreign letter.
I believe that I have to figure out how to append the string or something to that effect.
Here are the NSXMLParser files:
SearchXMLParser.h
#import <Foundation/Foundation.h>
#import "Search.h"
#interface SearchXMLParser : NSObject <NSXMLParserDelegate>
{
NSMutableString *currentNodeContent;
NSMutableArray *searchhits;
NSMutableArray *trackhits;
NSXMLParser *parser;
Search *currentSearch;
}
#property (readonly, retain) NSMutableArray *searchhits;
#property (readonly, retain) NSMutableArray *trackhits;
-(id) loadXMLByURL:(NSString *)urlString;
#end
SearchXMLParser.m
#import "SearchXMLParser.h"
#import "Search.h"
#implementation SearchXMLParser
#synthesize searchhits, trackhits;
-(id) loadXMLByURL:(NSString *)urlString
{
searchhits = [[NSMutableArray alloc] init];
trackhits = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"track"])
{
currentSearch = [Search alloc];
}
if ([elementname isEqualToString:#"track"])
{
currentSearch.trackurl = [attributeDict objectForKey:#"href"];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementname isEqualToString:#"name"])
{
[trackhits addObject:currentNodeContent];
}
if ([elementname isEqualToString:#"track"])
{
currentSearch.track = [trackhits objectAtIndex:0];
currentSearch.artist = [trackhits objectAtIndex:1];
currentSearch.album = [trackhits objectAtIndex:2];
[trackhits removeAllObjects];
[searchhits addObject:currentSearch];
[currentSearch release];
currentSearch = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"found characters: %#", string);
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void) dealloc
{
[parser release];
[super dealloc];
}
#end
I have already checked SO for answers and found a couple of similar posts, but nothing that gave a clear solution to this problem.
Can anyone shed some light on this problem? :) Any help is much appreciated!
your parser:foundCharacters: method does not work as it should.
This is from the NSXMLParserDelegate Protocol Reference
The parser object may send the delegate several parser:foundCharacters: messages to report the characters of an element. Because string may be only part of the total character content for the current element, you should append it to the current accumulation of characters until the element changes.
you could try something like this (ARC):
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"found characters: %#", string);
if (!currentNodeContent) {
currentNodeContent = [[NSMutableString alloc] init];
}
[currentNodeContent appendString:string];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// your code here
// when you are done with the string:
currentNodeContent = nil;
}

Desperate for NSXMLParser Guidance

I previously asked this question XMLParser Advice.
However I am still unable to get it to function properly....
So I guess I will start from scratch:
Located at a certain URL is an XML Tree that looks like this
<result>
//stuff that I dont need
<title>
//thing that I do need
</title>
//stuff that I dont need
<body>
//thing that I do need
</body>
<result>
How the heck do I go about parsing that?
The (useless) code I have so far can be found in the link at the top of this question.
Thank you for your time.
Write a simple class, which will be the parser's delegate.
#interface YourObject : NSObject <NSXMLParserDelegate> {
NSString *title, *body; // object attributes
NSXMLParser *parser; // will parse XML
NSMutableString *strData; // will contains string data being parsed
}
#property(readwrite, copy) NSString *title, body;
// will be used to set your object attributes
-(void)fetchValuesAtURL:(NSString *)url;
#end
The fetchValuesAtURL: method will initiate the parse operation.
#implementation YourObject
#synthesize title, body;
-(id)init {
self = [super init];
if(self) {
title = #"";
body = #"";
parser = nil;
strData = [[NSMutableString alloc] initWithCapacity:10];
}
return self;
}
-(void)fetchValuesAtURL:(NSString *)url {
if(parser) {
[parser release];
}
NSURL *xmlURL = [NSURL URLWithString:url];
parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[parser setDelegate:self];
[parser parse];
}
-(void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
// element is about to be parsed, clean the mutable string
[strData setString:#""];
}
// the probably missing method
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// content (or part of) has been found, append that to the current string
[strData appendString:string];
}
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
// element has been parsed, test the element name
// and store strData accordingly
if([elementName isEqualToString:#"title"]) {
self.title = strData;
}
else { // or else if, here you got two elements to parse
self.body = strData;
}
}
-(void)dealloc {
[title release];
[body release];
[strData release];
if(parser) {
[parser release];
}
[super dealloc];
}
#end
Then :
YourObject *obj = [[YourObject alloc] init];
[obj fetchValuesAtURL:#"http://www.site.com/xml/url"];
NSXMLParser's delegate is able to do many more things, as described in Event-Driven XML Programming Guide from Apple.
For complete reference on delegate methods, see NSXMLParserDelegate Protocol Reference.

Adding objects to an NSMutableArray, order seems odd when parsing from an XML file

I am parsing an XML file for two elements: "title" and "noType". Once these are parsed, I am adding them to an object called aMaster, an instance of my own Master class that contains NSString variables.
I am then adding these instances to an NSMutableArray on a singleton, in order to call them elsewhere in the program. The problem is that when I call them, they don't seem to be on the same NSMutableArray index... each index contains either the title OR the noType element, when it should be both... can anyone see what I may be doing wrong? Below is the code for the parser. Thanks so much!!
#import "XMLParser.h"
#import "Values.h"
#import "Listing.h"
#import "Master.h"
#implementation XMLParser
#synthesize sharedSingleton, aMaster;
- (XMLParser *) initXMLParser {
[super init];
sharedSingleton = [Values sharedValues];
aMaster = [[Master init] alloc];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
aMaster = [[Master alloc] init];
//Extract the attribute here.
if ([elementName isEqualToString:#"intro"]) {
aMaster.intro = [attributeDict objectForKey:#"enabled"];
} else if ([elementName isEqualToString:#"item"]) {
aMaster.item_type = [attributeDict objectForKey:#"type"];
//NSLog(#"Did find item with type %#", [attributeDict objectForKey:#"type"]);
//NSLog(#"Reading id value :%#", aMaster.item_type);
} else {
//NSLog(#"No known elements");
}
//NSLog(#"Processing Element: %#", elementName); //HERE
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else {
[currentElementValue appendString:string];//[tempString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
CFStringTrimWhitespace((CFMutableStringRef)currentElementValue);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[sharedSingleton.master addObject:aMaster];
NSLog(#"Added %# and %# to the shared singleton", aMaster.title, aMaster.noType); //Only having one at a time added... don't know why
[aMaster release];
aMaster = nil;
} else if ([elementName isEqualToString:#"title"]) {
[aMaster setValue:currentElementValue forKey:#"title"];
} else if ([elementName isEqualToString:#"noType"]) {
[aMaster setValue:currentElementValue forKey:#"noType"];
//NSLog(#"%# should load into the singleton", aMaster.noType);
}
NSLog(#"delimiter");
NSLog(#"%# should load into the singleton", aMaster.title);
NSLog(#"%# should load into the singleton", aMaster.noType);
[currentElementValue release];
currentElementValue = nil;
}
- (void) dealloc {
[aMaster release];
[currentElementValue release];
[super dealloc];
}
#end
Every time that didStartElement is called, you're setting aMaster to a new instance of the Master class. Based on the implementation of didEndElement, it looks like you should only be creating a new instance whenever a new item tag is found. This could be why each entry in the array has one value or the other, since a new instance is created for each value.