gpt4 book ai didi

ios - 使用 NSXMLparser,如何解析具有相同名称标签但元素不同的 xml 文件?

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:30:23 26 4
gpt4 key购买 nike

是否可以在 NSXMLparser 中给出路径表达式?我有一个 XML 文件,其中有几个相同的名称标签,但它们位于不同的元素中。有什么方法可以区分它们。这是 XML:

<Schools>
<School>
<ID>335823</ID>
<Name>Fairfax High School</Name>
<Student>
<ID>4195653</ID>
<Name>Will Turner</Name>
</Student>
<Student>
<ID>4195654</ID>
<Name>Bruce Paltrow</Name>
</Student>
<Student>
<ID>4195655</ID>
<Name>Santosh Gowswami</Name>
</Student>
</School>
<Schools>

最佳答案

我会创建单独的 SchoolStudent对象。您的解析器将具有 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*/
}

抱歉,我的代码太短了,我现在没有太多时间打字。如果需要更多详细信息,我可以稍后添加更多代码。


更新

对我来说,了解更多细节的最快方法就是显示我正在寻找的内容的代码,并将解释所有内容的注释放入代码中。如果对其中的任何部分有任何疑问,或者需要进一步解释任何内容,请告诉我需要详细说明的内容,我会尽力而为。

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

学校XML.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

学校XML.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.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 <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");
}
}

关于ios - 使用 NSXMLparser,如何解析具有相同名称标签但元素不同的 xml 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16462782/

26 4 0