Nsxmlparser on iOS, How to Use It Given a Xml File

NSXMLParser on iOS, how do I use it given a xml file

The simplest thing is to do something like this:

NSXMLParser *xmlParser = [[NSXMLParser alloc]initWithData:];
[xmlParser setDelegate:self];
[xmlParser parse];

Notice that setDelegate: is setting the delegate to 'self', meaning the current object. So, in that object you need to implement the delegate methods you mention in the question.

so further down in your code, paste in:

    - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict{

NSLog(@"I just found a start tag for %@",elementName);
if ([elementName isEqualToString:@"employee"]){
// then the parser has just seen an opening tag
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"the parser just found this text in a tag:%@",string);
}

etc. etc.

It's a little harder when you want to do something like set a variable to the value of some tag, but generally it's done using a class variable caleld something like "BOOL inEmployeeTag" which you set to true (YES) in the didStartElement: method and false in the didEndElement: method - and then check for it's value in the foundCharacters method. If it's yes, then you assign the var to the value of string, and if not you don't.

richard

Parsing XML file with NSXMLParser - getting values

First you need to create an object that does the parsing. It will instatiate the NSXMLParser instance, set itself as the delegate for the parser and then call the parse message. It can also be responsible for storing your four result arrays:

NSXMLParser * parser = [[NSXMLParser alloc] initWithData:_data];
[parser setDelegate:self];
BOOL result = [parser parse];

The message you are most interested in implementing in your delegate objects is didStartElement. This guy gets called for each element in your XML file. In this callback you can add your name, price & where attributes to their respective arrays.

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
// just do this for item elements
if(![elementName isEqual:@"item"])
return;

// then you just need to grab each of your attributes
NSString * name = [attributeDict objectForKey:@"name"];

// ... get the other attributes

// when we have our various attributes, you can add them to your arrays
[m_NameArray addObject:name];

// ... same for the other arrays
}

using NSXMLparser, how do you parse an xml file which has same name tags but in different elements?

I'd create separate School and Student objects. Your parser will have properties for currentSchool and currentStudent. Whenever your parser hits the tag, call

self.currentStudent = [[MyStudentObject alloc] init];

Whenever your parser hits the tag, call

self.currentStudent = nil;

Then, when you hit the tag, you can check to see if you have a currentStudent. If you do, then the name is the name of that student. If there is no current student, then the name is the name of the school.

if (self.currentStudent)
{
self.currentStudent.name = /*string between tags*/
}
else
{
self.currentSchool.name = /*string between tags*/
}

Sorry my code pieces are so brief, I don't have much time to type this now. If more detail is needed, I can add more code later.


UPDATE

The quickest way for me to go into more detail is just to show the code for what I'm looking for, and put the comments explaining everything into the code. If there are any questions on any part of this, or if anything needs to be explained further, let me know what to elaborate on and I'll do my best.

StudentXML.h

#import 

@interface StudentXML : NSObject

@property (nonatomic, strong) NSString *ID; // MAKE SURE THIS EXACTLY MATCHES THE ELEMENT IN THE XML!!
@property (nonatomic, strong) NSString *Name; // MAKE SURE THIS EXACTLY MATCHES THE ELEMENT IN THE XML!!

@end

StudentXML.m

#import "StudentXML.h"

@implementation StudentXML

@end

SchoolXML.h

#import 
#import "StudentXML.h"

@interface SchoolXML : NSObject

@property (nonatomic, strong) NSString *ID; // MAKE SURE THIS EXACTLY MATCHES THE ELEMENT IN THE XML!!
@property (nonatomic, strong) NSString *Name; // MAKE SURE THIS EXACTLY MATCHES THE ELEMENT IN THE XML!!
@property (nonatomic, strong) NSMutableArray *studentsArray; // Array of StudentXML objects

@end

SchoolXML.m

#import "SchoolXML.h"

@implementation SchoolXML

// Need to overwrite init method so that array is created when new SchoolXML object is created
- (SchoolXML *) init;
{
if (self = [super init])
{
self.studentsArray = [[NSMutableArray alloc] init];

return self;
}
else
{
NSLog(@"Error - SchoolXML object could not be initialized in init on SchoolXML.m");
return nil;
}
}

@end

SchoolsParser.h

#import 
#import "SchoolXML.h"
#import "StudentXML.h"

@interface SchoolsParser : NSObject
{
NSMutableString *currentElementValue; // Will hold the string between tags until we decide where to put it
}

@property (nonatomic, strong) SchoolXML *currentSchool; // Will hold the school that is in the process of being filled
@property (nonatomic, strong) StudentXML *currentStudent; // Will hold the student that is in the process of being filled
@property (nonatomic, strong) NSMutableArray *allSchools; // This is the final list of all the data in the XML file

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

@end

SchoolsParser.m

#import "SchoolsParser.h"

@implementation SchoolsParser

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
// This method will be hit each time the parser sees an opening tag
// elementName is the string between the <> (example "School")
{
if ([elementName isEqualToString:@"School"])
{
self.currentSchool = [[SchoolXML alloc] init];
}
else if ([elementName isEqualToString:@"Student"])
{
self.currentStudent = [[StudentXML alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
// This method will be hit each time the parser sees a string between tags
// string is the value between the open and close tag (example "Fairfax High School")
// We take string and hold onto it until we can decide where it should be put
{
currentElementValue = [[NSMutableString alloc] initWithString:string];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
// This method will be hit each time the parser sees an closing tag
// elementName is the string between the (example "School")
// This is the method where we decide where we want to put the currentElementValue string
{
if ([elementName isEqualToString:@"Student"])
{
// Put the current student into the studentsArray of the currentSchool
[self.currentSchool.studentsArray addObject:self.currentStudent];

// We've finished building this student and have put it into the school we wanted, so we clear out currentStudent so we can reuse it next time
self.currentStudent = nil;
}
else if ([elementName isEqualToString:@"School"])
{
// Put the current school into the allSchoolsArray to send back to our view controller
[self.allSchools addObject:self.currentSchool];

// We've finished building this school and have put it into the return array, so we clear out currentSchool so we can reuse it next time
self.currentSchool = nil;
}
else if ([elementName isEqualToString:@"Schools"])
{
// We reached the end of the XML document
return;
}
else
// This is either a Name or an ID, so we want to put it into the correct currentSomething we are building
{
if (self.currentStudent)
// There is a currentStudent, so the Name or ID we found is that of a student
{
// Since the properties of our currentStudent object exactly match the elementNames in our XML, the parser can automatically fills values in where they need to be without us doing any more
// For example, it will take "Will Turner" in the tags in the XML and put it into the .Name property of our student
[self.currentStudent setValue:currentElementValue forKey:elementName];
}
else
// There was no student, so the Name or ID we found is that of a school
{
// Since the properties of our currentStudent object exactly match the elementNames in our XML, the parser can automatically fills values in where they need to be without us doing any more
// For example, it will take "Fairfax High School" in the tags in the XML and put it into the .Name property of our school
[self.currentSchool setValue:currentElementValue forKey:elementName];
}
}

// We've now put the string in currentElementValue where we wanted it, so we clear out currentElementValue so we can reuse it next time
currentElementValue = nil;
}

-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"Error in SchoolsParser.m");
NSLog(@"%@",parseError.description);
}

@end

UIViewController.m where you want to start parsing (make sure you #include SchoolXML, StudentXML, and SchoolsParser):

- (void) startSchoolParser
{
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:responseData]; // where "responseData" is the NSData object that holds your XML
SchoolsParser *parser = [[SchoolsParser alloc] init];
[nsXmlParser setDelegate:parser];
if ([nsXmlParser parse])
{
// Parsing was successful
NSArray *allSchools = parser.allSchools;
// You can now loop through allSchools and use the data how ever you want

// For example, this code just NSLog's all the data
for (SchoolXML *school in allSchools)
{
NSLog(@"School Name = %@",school.Name);
NSLog(@"School ID = %@",school.ID);
for (StudentXML *student in school.studentsArray)
{
NSLog(@"Student Name = %@",student.Name);
NSLog(@"Student ID = %@",student.ID);
}
}
}
else
{
NSLog(@"Parsing Failed");
}
}

retrieve xml file using nsxmlparser in ios

Speaking from a developers perspective I would not recommend using NSXMLParser due to it's laborious way to parse XML Files. There is a great write up about choosing the right XML Parser.

I use KissXML quite often.
You can find a quit tutorial of using it here.

Hope this helps.

NSXMLParser example

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentKey = nil;
[currentStringValue release];
currentStringValue = nil;
if([elementName isEqualToString:@"Value"]){
//alloc some object to parse value into
} else if([elementName isEqualToString:@"Signature"]){
currentKey = @"Signature";
return;
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if(currentKey){
if(!currentStringValue){
currentStringValue = [[NSMutableString alloc] initWithCapacity:200];
}
[currentStringValue appendString:string];
}
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:@"Signature"] && [currentStringValue intValue] == 804){
ivar.signature = [currentStringValue intValue];
return;
}
}

Something like this.
Note I havent really tested this code on compiler so there will be syntax errors here & there.

How can i Parse this xml using NSXMLParser in ios?

Try this:

- (void)viewDidLoad {
[super viewDidLoad];

NSURL *url = [[NSURL alloc] initWithString:@"yourURL"];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
BOOL result = [parser parse];
// Do whatever with the result
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
NSLog(@"Did start element");
if ([elementName isEqualToString:@"root"]) {
NSLog(@"found rootElement");
return;
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSLog(@"Did end element");
if ([elementName isEqualToString:@"root"]) {
NSLog(@"rootelement end");
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSString *tagName = @"column";
if ([tagName isEqualToString:@"column"]) {
NSLog(@"Value %@",string);
}
}

XML file not parsing using NSXMLParser in iOS

Typo!

if ([elementName isEqualToString:@"radio"] && isRadio){

Should be:

if ([elementName isEqualToString:@"emri"] && isRadio){
// ^^^^

Also isRadio should really be inRadio, to be more descriptive.



Related Topics



Leave a reply



Submit