How can I parse an XML file in Objective C - ios

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);
}];

Related

Display number of XML elements in a textfield

I have an XML file somewhere on the web with a couple of profiles inside it and I want the number of profiles to be displayed in a textfield.
I have a textfield called: numberOfProfiles.. so what should I do in viewDidLoad?
numberOfProfiles.Text = ???
The XML file is being parsed like this:
NSMutableString *currentNodeContent;
NSXMLParser *parser;
ViewController *currentProfile;
bool isStatus;
ViewController *xmlParser;
-(id)loadXMLByURL:(NSString *)urlString
{
profile = [[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:#"firstname"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
if([elementName isEqualToString:#"lastname"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
if([elementName isEqualToString:#"email"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
if([elementName isEqualToString:#"address"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"firstname"])
{
currentProfile->firstName = currentNodeContent;
NSLog(#"%#",currentProfile->firstName);
[profile addObject:currentProfile];
}
if([elementName isEqualToString:#"lastname"])
{
currentProfile->lastName = currentNodeContent;
NSLog(#"%#",currentProfile->lastName);
[profile addObject:currentProfile];
}
if([elementName isEqualToString:#"email"])
{
currentProfile->eMail = currentNodeContent;
NSLog(#"%#",currentProfile->eMail);
[profile addObject:currentProfile];
}
if([elementName isEqualToString:#"address"])
{
currentProfile->address = currentNodeContent;
NSLog(#"%#",currentProfile->address);
[profile addObject:currentProfile];
}
if([elementName isEqualToString:#"profiles"])
{
[self->profile addObject:currentProfile];
currentProfile = nil;
currentNodeContent = nil;
setText:currentProfile->lastName;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
xmlParser = [[ViewController alloc] loadXMLByURL:#"http://dierenpensionlindehof.nl/profiles.xml"];
}
Thanks in advance!
for just count of element you can have an instance variable like of int type numberOfProfilesCount and you can increment this in
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
numberOfProfilesCount++;
}
and in
- (void)parserDidEndDocument:(NSXMLParser *)parser {
numberOfProfiles.Text = [NSString stringWithFormate:#"%d", numberOfProfilesCount];
}
to show your element count
Assuming profile is a global variable, use [profile count] to get the number of profiles.
The try: [numberOfProfiles setText:[[profile count] stringValue]

How to get path of tag in xml while using NSXmlParser in iphone?

I am new to iphone development. In my application, there are multiple tags are of the same name. I want to get the path of the tags so that i make it sure that i get the right tag.
My xml structure is like
<items>
<name></name>
<link></link>
<items>
<name></name>
<link></link>
</items>
</items>
Needed exactly the same thing, guess this is an old question but I will write down what I have implemented:
- (void) parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(#"parserDidStartDocument");
self.errorParsingDictionary = [NSMutableDictionary dictionary];
self.nodeStack = [NSMutableArray array];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"didStartElement --> %#", elementName);
[self.nodeStack addObject:elementName]; // Push
NSString *currentPath = [self pathFromNodeStack];
// [self.errorParsingDictionary setObject:[NSMutableDictionary dictionary]
// forKey:currentPath];
[self.errorParsingDictionary setValue:[NSMutableDictionary dictionary]
forKeyPath:currentPath];
}
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(#"foundCharacters --> %#", string);
NSString *currentPath = [self pathFromNodeStack];
// NSMutableString *mutableString = [self.errorParsingDictionary objectForKey:currentPath];
id nodeValue = [self.errorParsingDictionary valueForKeyPath:currentPath];
NSMutableString *nodeString = nil;
if (nil==nodeValue || ![nodeValue isKindOfClass:[NSString class]])
{
nodeString = [NSMutableString string];
// [self.errorParsingDictionary setObject:mutableString
// forKey:currentPath];
[self.errorParsingDictionary setValue:nodeString
forKeyPath:currentPath];
}
[nodeString appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSLog(#"didEndElement --> %#", elementName);
[self.nodeStack removeObjectAtIndex:[self.nodeStack count]-1]; // Pop
}
- (void) parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"parserDidEndDocument");
self.nodeStack = nil;
}
-(NSString*)pathFromNodeStack
{
NSMutableString *path = [NSMutableString string];
for (int i=0; i<self.nodeStack.count; i++)
{
[path appendString:[self.nodeStack objectAtIndex:i]];
if (i!=self.nodeStack.count-1)
{
// If it is not the last object
[path appendString:#"."];
}
}
return path;
}
After the completion of parsing, you can now use the dictionary: self.errorParsingDictionary to get the values of any path, like this:
NSString *nodeValue = [self.errorParsingDictionary valueForKeyPath: #"items.items.name"];
Hope this helps.

Twitter Feed not showing full tweet

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..

NSXMLParserDelegate not responding

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];

NSXMLParser issue : don't get all my items and no data

I have some difficulties to understand how to use NSXMLParser despite all the tutos I've watched...
I have the following XML file with for example :
<rss>
<channel>
<title>The Title</title>
<link>A URL</link>
<language>English</language>
<item>
<name>John</name>
<title>John4034</title>
<city>LA</city>
<country>USA</country>
</item>
....
<item>
<name>Marc</name>
<title>Marc2942</title>
<city>London</city>
<country>England</country>
</item>
</channel>
</rss>
I aim to stock all the items in a NSMutableArray of Item. My class Item has 4 NSString (name, title, city, country).
Here is my XMLParser.m file :
- (id) loadXMLbyURL : (NSString *) urlString
{
items = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL: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:#"item"]) currentItem = [Item alloc];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"name"]) [currentItem setName:currentNodeContent];
if([elementName isEqualToString:#"title"]) [currentItem setTitle:currentNodeContent];
if([elementName isEqualToString:#"city"]) [currentItem setCity:currentNodeContent];
if([elementName isEqualToString:#"country"]) [currentItem setCountry:currentNodeContent];
}
if([elementName isEqualToString:#"item"])
{
[self.items addObject:currentItem];
currentItem = nil;
currentNodeContent = nil;
}
}
But with all this, I have 2 issues :
My array of items only contains 108 indexes whereas my XML file got 299.
I've no data in my items properties... everything is (null) when I try to print it in the log.
Please help !
If anybody has the same problem, I finally found the solution.
The problem of non-checking all the XML file was because of a PCDATA error in the XML file.
The problem of getting nothing in the NSStrings has been solved in this thread : NSXMLParser issue : don't get all data?

Resources