I'm parsing a very simple XML document with XCode. Sometimes it works just fine, other times it returns this:
document.cookie='lllllll=9bb65648lllllll_9bb65648; path=/';window.location.href=window.location.href;
Here is my header file:
#interface NewsViewController : UIViewController{
NSXMLParser *rssParser;
NSMutableArray *articles;
NSMutableDictionary *item;
NSString *currentElement;
NSMutableString *ElementValue;
BOOL errorParsing;
}
#property (weak, nonatomic) IBOutlet UILabel *newsText;
#property (retain) NSMutableString *theString;
- (void)parseXMLFileAtURL:(NSString *)URL;
#end
Here is my implementation code:
-(void)viewDidLoad{
[self parseXMLFileAtURL:#"http://www.domain.com/news.xml"];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(#"File found and parsing started");
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
NSString *agentString = #"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:URL]];
[request setValue:agentString forHTTPHeaderField:#"User-Agent"];
NSData *xmlFile = [ NSURLConnection sendSynchronousRequest:request returningResponse: nil error: nil ];
articles = [[NSMutableArray alloc] init];
errorParsing=NO;
rssParser = [[NSXMLParser alloc] initWithData:xmlFile];
[rssParser setDelegate:self];
// You may need to turn some of these on depending on the type of XML file you are parsing
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString *errorString = [NSString stringWithFormat:#"Error code %i", [parseError code]];
NSLog(#"Error parsing XML: %#", errorString);
errorParsing=YES;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
ElementValue = [[NSMutableString alloc] init];
if ([elementName isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
[ElementValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]) {
[articles addObject:[item copy]];
} else {
[item setObject:ElementValue forKey:elementName];
NSLog (#"--%#",ElementValue);
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
if (errorParsing == NO)
{
NSLog(#"XML processing done!");
theString=[NSString stringWithFormat:#"%#",ElementValue];
NSLog (#"Parsed: %#",theString);
} else {
NSLog(#"Error occurred during XML processing");
}
}
I'm fairly stumped, but I'm sure it must be something simple I can't see. Any tips?
the response you are trying to parse (probably) is not in XML.
NSLog your xml responses, and see whats being returned by the server when it returns the strange code. Validate the xml before parsing it.
Related
I'm trying to parse data from a Wordpress RSS feed using NSXMLR. My problem is exporting my parsed data. So far I have,
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]){
currentTitle = [[NSMutableString alloc] init];
item = [[NSMutableDictionary alloc] init];
}
}
this class
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]){
[item setObject:currentTitle forKey:#"title"];
}
[stories addObject:item];
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"title"]){
[currentTitle appendString:string];
}
}
NSMutableArray *stories;
NSMutableDictionary *item;
So in ViewDidLoad implementation, I have
//declare the object of allocated variable
NSData *xmlData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"URL"]];// URL that given to parse.
//allocate memory for parser as well as
xmlParserObject =[[NSXMLParser alloc]initWithData:xmlData];
[xmlParserObject setDelegate:self];
//asking the xmlparser object to beggin with its parsing
[xmlParserObject parse];
NSLog(#"%#", [item objectForKey:#"title"]);
My problem is that I only print one object, I have multiples elements. How can I make it scan every single one of them and print them all.
Thanks in advance.
If I understand your code correctly, item holds the currently parsed item,
and the array stories holds all items.
So you have to allocate the stories array first:
stories = [[NSMutableArray alloc] init];
Then you do the parsing (but you should add an error check):
NSData *xmlData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"URL"]];
xmlParserObject =[[NSXMLParser alloc]initWithData:xmlData];
[xmlParserObject setDelegate:self];
if (![xmlParserObject parse]) {
// Parsing failed, report error...
}
And finally print the contents of the array:
for (NSDictionary *story in stories) {
NSLog(#"%#", [story objectForKey:#"title"]);
}
The didEndElement method probably should look like this:
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]){
[item setObject:currentTitle forKey:#"title"];
[stories addObject:item]; // <-- MOVED INTO THE IF-BLOCK
}
}
I am using NSXmlParser to get data from XML. In the parser delegate method I have:
- (void)resetPassCallback: (NSData*) data{
NSLog(#"start parsing the data");
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:data];
[nsXmlParser setDelegate:self];
BOOL success = [nsXmlParser parse];
if (success) {
NSLog(#"No errors %#", xmlArray);
} else {
NSLog(#"Error parsing document!");
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qualifiedName attributes: (NSDictionary *)attributeDict
{
element = elementName;
if([elementName isEqualToString:#"User"])
{
XmlDict = [[NSMutableDictionary alloc]init];
userId =[[NSMutableString alloc]init];
screenName =[[NSMutableString alloc]init];
xmlArray = [[NSMutableArray alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(#"foundCharacters ::::: %# :::: ", string);
[xmlArray addObject:string];
}
Although I am able to parse the data, I am not getting the complete data. In the console, the log shows:
foundCharacters ::::: 200 ::::
foundCharacters ::::: f1f47453-04d7-20c8-a9e1-406fdc89a2da ::::
foundCharacters ::::: test ::::
foundCharacters ::::: 62e2092a-eb6e-44ad-7a7b-3deb976569c1 ::::
foundCharacters ::::: Thomas ::::
xmlArray contents : (
"62e2092a-eb6e-44ad-7a7b-3deb976569c1",
Thomas
)
As you can see, why am I not getting the “test” and other values in the xmlArray.
why use for mutableArray. simply try this
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
I hope that, the Array is getting re-initialed at every time of NSXMLParser delegates called .
You need to initialise the Array, before the NSXMLParser delegates
called.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qualifiedName attributes: (NSDictionary *)attributeDict
{
//Don't initialise your NSArray here
}
}
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(#"foundCharacters ::::: %# :::: ", string);
[xmlArray addObject:string];
}
Use xmlArray = [[NSMutableArray alloc]init]; in
- (void)resetPassCallback: (NSData*) data{
NSLog(#"start parsing the data");
xmlArray = [[NSMutableArray alloc]init];
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:data];
[nsXmlParser setDelegate:self];
BOOL success = [nsXmlParser parse];
if (success) {
NSLog(#"No errors %#", xmlArray);
} else {
NSLog(#"Error parsing document!");
}
}
not in
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qualifiedName attributes: (NSDictionary *)attributeDict
{
}
I'm trying to parse this xml file. The problem I'm having is that I'd like to use the
-(void)parser:(NSXMLParser*)parser didStartElement ...
to drill down into several levels of this xml file.
This is what I have so far:
#pragma didStartElement (from the parser protocol)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// Choose the tag
if ([elementName isEqualToString:#"item"]) {
NSString *firstName = [attributeDict valueForKey:#"firstname"];
NSString *lastName = [attributeDict valueForKey:#"lastname"];
NSString *birthDay = [attributeDict valueForKey:#"birthday"];
Politician *politician = [[Politician alloc] initWithName:firstName lName:lastName bDay:birthDay];
if (politician != nil) {
[people addObject:politician];
}
}
}
The problem is that this code does not drill down. Is there a way to selectively start the parsing from a specific tag (say: person) and check for the keys of that tag or to rewrite the "elementName's" value so I can use multipe if statements? What's the right way of doing this? Thanks much.
You couldnt get the firstname,lastname,etc in your attributeDict. Attribute dictionary holds values like in the below format
<count n="1">
In the above example attributeDict holds the value for n
In order to parse the given xml, you can use the below code.
Declare the objects
Politician *politician;
NSString *curElement;
NSMutableArray *politicians;
BOOL isCongressNumbers;
Initialize the politicians in viewDidLoad
politicians = [[NSMutableArray alloc]init];
Add the delegate methods
#pragma mark - NSXMLParser Delegate
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"item"]) {
politician = [[Politician alloc]init];
} else if ([elementName isEqualToString:#"congress_numbers"]) {
isCongressNumbers = YES;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
curElement = string;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"item"] && !isCongressNumbers) {
[politicians addObject:politician];
} else if ([elementName isEqualToString:#"firstname"]) {
politician.name = curElement;
} else if ([elementName isEqualToString:#"lastname"]) {
politician.lName = curElement;
} else if ([elementName isEqualToString:#"birthday"]) {
politician.bDay = curElement;
} else if ([elementName isEqualToString:#"congress_numbers"]) {
isCongressNumbers = NO;
}
}
You can
1) new a Politician in the didStartElement method and assign the element name in one instance variable.
2) assign the properties of Politician in the foundCharacters according to the instance variable you assigned in 1).
3) add the Politician to the people in the didEndElement.
Hope this is helpful.
The sample code is as follows:
declare some instance variables:
Politican *politican;
NSString *currentElement;
NSMutableArray *politicians;
init the arrays:
politicians = [[NSMutableArray alloc] init];
implement the delegate methods.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = elementName;
if ([elementName isEqualToString:#"item"]) {
politician = [[Politician alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length<1)
return; // avoid some white space
if ([currentElement isEqualToString:#"firstname"]) {
politician.firstname = string;
} else if ([currentElement isEqualToString:#"lastname"]) {
politician.lastname = string;
} else if ([currentElement isEqualToString:#"birthday"]) {
politician.birthday = string;
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"item"]) {
[politicians addObject:politician];
}
}
Anyway this is just a sample, you'd better write all the if else statements according to your xml.
In your xml file, there are several tags named the same item. you can try to make one more instance variable to store the previous tag to make the difference and do the assignments.
In.h file
#property (strong, nonatomic) NSXMLParser *xmlParser;
#property (nonatomic, retain) NSMutableDictionary *lResponseDict;
#property (nonatomic, weak) NSString *currentElement;
NSString* UDID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(#"UDID:: %#", UDID);
NSString *urlString = [NSString stringWithFormat:#"urlHere"];
NSString *jsonString = [NSString stringWithFormat:LOGIN,self.cUsernameTxtFld.text,self.cPasswordTxtFld.text,UDID];
NSData *myJSONData =[jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/html" forHTTPHeaderField:#"Accept"];
NSMutableData *body = [NSMutableData data];
[body appendData:[NSData dataWithData:myJSONData]];
[request setHTTPBody:body];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *str = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
if(str.length > 0)
{
self.xmlParser = [[NSXMLParser alloc] initWithData:urlData];
self.xmlParser.delegate = self;
// Start parsing.
[self.xmlParser parse];
}
#pragma mark - NSXML Parsar Delegate Methods.
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
// NSLog(#"Parsing Initiated.");
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
self.currentElement = elementName;
if([elementName isEqualToString:#"data"])
{
// NSLog(#"%#",elementName);
self.lResponseDict = [[NSMutableDictionary alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"data"])
{
// NSLog(#"%#",elementName);
NSLog(#"Final Dict: %#", _lResponseDict);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//NSLog(#"%#", string);
[_lResponseDict setObject:string forKey:_currentElement];
}
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
}
Hope you are getting the URL data ... so with SMXMLParser, it is easier to parse using one by one node ...
In the below mentioned example, I am using AFNetworking with SMXMLParser . Hope you get the idea ....
NSString *soapRequest=[NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
// Your parameters here …. //
"</soap:Body>\n"
"</soap:Envelope>\n"];
NSString *urlStr = #"Your URL";
NSURL *urlNew = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request=[appDel generateRequestWithUrl:urlNew request:soapRequest];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error=nil;
dictCarList = [[NSMutableDictionary alloc]init];
SMXMLDocument *document=[[SMXMLDocument alloc]initWithData:operation.responseData error:&error];
if (error) {
NSLog(#"Error while parsing the document: %#", error);
[indicatorView removeFromSuperview];
return;
}
count++;
SMXMLElement *element1 = [document.root childNamed:#"objects"];
SMXMLElement *element2 = [element1 childNamed:#"The Tag you want to get"];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error:%#",error);
}];
So I am making an app that one part of it displays the users tweets in a table view. However there's something getting corrupted with some tweets such as its only showing a single character such as (") or an emoji character. In example if the tweet says:
RT #jakemillermusic: Everyone upload your pics that you took today during the ustream and caption it "follow #jakemillermusic #jakemiller"
when shown with NSLog it prints :
2013-04-03 00:34:30.476 ParsingXMLTutorial[3308:c07] RT #jakemillermusic: Everyone upload your pics that you took today during the ustream and caption it
2013-04-03 00:34:30.476 ParsingXMLTutorial[3308:c07] "
2013-04-03 00:34:30.477 ParsingXMLTutorial[3308:c07] follow #jakemillermusic #jakemiller
2013-04-03 00:34:30.478 ParsingXMLTutorial[3308:c07] "
Here's the URL I am using to fetch the XML format:
http://api.twitter.com/1/statuses/user_timeline/LexxiSaal.xml?include_entities=true&include_rts=true&screen_name=twitterapi&trim_user=false&contributor_details=true&count=50
HERES THE PARSING CODE:
-(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
{
//string = [string stringByReplacingOccurrencesOfString:#" " withString:#""]; // space
string = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""]; // newline
string = [string stringByReplacingOccurrencesOfString:#"\t" withString:#""];
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:#"status"])
{
currentTweet = [Tweet alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"user"])
{
isStatus = NO;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"created_at"])
{
currentTweet.dateCreated = currentNodeContent;
}
if ([elementname isEqualToString:#"text"])
{
currentTweet.content = currentNodeContent;
}
}
if ([elementname isEqualToString:#"status"])
{
[self.tweets addObject:currentTweet];
currentTweet = nil;
currentNodeContent = nil;
}
}
#end
I would suggest few changes as below
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSString *value=[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet];
if(currentNodeContent == nil){
currentNodeContent = [[NSMutableString alloc] initWithString:value];
}else
[currentNodeContent appendString:value];
}
and in didEnd
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"created_at"])
{
currentTweet.dateCreated = currentNodeContent;
}
if ([elementname isEqualToString:#"text"])
{
currentTweet.content = currentNodeContent;
}
}
if ([elementname isEqualToString:#"status"])
{
[self.tweets addObject:currentTweet];
currentTweet = nil;
//currentNodeContent = nil; REMOVED
}
currentNodeContent = nil; // PUT OUTSIDE
}
The thing is you have to append string in method foundCharacters because the parser doesn't return all the string in between the tags at once..
And at last you should make the currentNodeContent nil, in the didEnd method globally because you are using it for other texts too.
Hope above helps..
I am trying to develop an XML parser in objective-C using the method described in http://wiki.cs.unh.edu/wiki/index.php/Parsing_XML_data_with_NSXMLParser.
I have coded up the entire flow but the delegate call back methods just won't respond!
Please take a look at the following code blocks and let me know if you could figure out any mistakes/errors...
Parser is being called from:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"cache" ofType:#"xml"];
NSLog(#"Path location is : %#",filePath);
NSData* xmlData = [NSData dataWithContentsOfFile:[NSURL URLWithString:filePath]];
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlData];
if(nsXmlParser!=NULL)
{
NSLog(#"parser is %#",nsXmlParser);
}
HDDataXML *parser = [[HDDataXML alloc] initXMLParser];
[nsXmlParser setDelegate:parser];
BOOL success = [nsXmlParser parse];
// test the result
if (success)
{
NSLog(#"No errors - effects count : i");
} else
{
NSLog(#"Error parsing document!");
}
All I see here is Error parsing document! The filePath variable is OK and the parser is not null.
Now, in the delegate's .h file:
#import <Foundation/NSObject.h>
#import "EffectsCache.h"
#class EffectsCache;
#interface HDDataXML : NSObject<NSXMLParserDelegate>
{
EffectsCache *effectsHandler;
NSMutableString *currentElementValue;
NSMutableArray *effects;
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string ;
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName;
- (HDDataXML *) initXMLParser;
#property (nonatomic, retain) EffectsCache *effectsHandler;
#property (nonatomic, retain) NSMutableArray *effects;
#end
And in the implementation of the delegate in .m:
#import "HDDataXML.h"
#implementation HDDataXML
#synthesize effects, effectsHandler;
- (HDDataXML *) initXMLParser
{
[super init];
effects = [[NSMutableArray alloc] init];
return self;
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
NSLog(#"started parsing");
if ([elementName isEqualToString:#"effects"]) {
NSLog(#"effects element found – create a new instance of EffectsCache class...");
effectsHandler = [[EffectsCache alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"mid parsing");
if (!currentElementValue)
{
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
else
{
[currentElementValue appendString:string];
}
NSLog(#"Processing value for : %#", string);
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
NSLog(#"done parsing");
if ([elementName isEqualToString:#"effects"])
{
return;
}
if ([elementName isEqualToString:#"effect"])
{
[effectsHandler addObject:effects];
[effectsHandler release];
effectsHandler = nil;
}
else
{
NSLog(#"cuurent value - %#",currentElementValue);
[effects setValue:currentElementValue forKey:elementName];
}
[currentElementValue release];
currentElementValue = nil;
}
Point is, the call back methods are not working.
Please help me find the bug.
Thanks in advance.
nsXmlParser.delegate = self;
[nsXmlParser parse];
and dont forget in the .h file to call the delegate
<NSXMLParserDelegate>
Ok... I solved it, finally:
As suggested by Martin R, I changed the code for calling the delegate:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"effects_cache" ofType:#"xml"];
NSLog(#"Path location is : %#",filePath);
NSData* xmlData = [NSData dataWithContentsOfFile:filePath];
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:xmlData];
Before doing this modification, the xmlData was null.
One other small modification was needed:
change:
[effectsHandler addObject:effects];
TO
[effects setValue:currentElementValue forKey:elementName];