我會創建單獨的School
和Student
對象。您的解析器將具有currentSchool
和currentStudent
的屬性。每當你的解析器打<Student>
標籤,撥打
self.currentStudent = [[MyStudentObject alloc] init];
每當你的解析器打</Student>
標籤,撥打
self.currentStudent = nil;
然後,當你打<name>
標籤,你可以檢查看看,如果你有一個currentStudent
。如果你這樣做,那麼這個名字就是那個學生的名字。如果沒有現在的學生,那麼這個名字就是學校的名字。
if (self.currentStudent)
{
self.currentStudent.name = /*string between <name> tags*/
}
else
{
self.currentSchool.name = /*string between <name> tags*/
}
對不起我的代碼片段是如此短暫,我沒有太多的時間,現在鍵入此。如果需要更多細節,我可以稍後添加更多代碼。
UPDATE
對我來說,進入更詳細的最快方法是隻是爲了顯示我正在尋找的代碼,並把一切都解釋成代碼中的註釋。如果對此有任何疑問,或者需要進一步解釋,請告訴我要詳細說明的內容,我會盡我所能。
StudentXML.h
#import <Foundation/Foundation.h>
@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 <Foundation/Foundation.h>
#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 <Foundation/Foundation.h>
#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。米
#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 <Name> 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 <Name> 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要開始解析(請確保您#include
SchoolXML,StudentXML和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");
}
}
您的XML在最後的結束標記上也缺少'/'。 – Rob 2013-05-09 15:42:15