iPhone - 解析 XML 文件 - 请帮忙!

发布于 2024-10-06 16:23:58 字数 4968 浏览 0 评论 0原文

我需要解析 xml 文件的帮助。我的问题是我不知道如何实现 didEndElement 委托。
我想要的是,我将有 2 个单元格,其中将展示旧约和新约,然后是圣经书籍和章节。 如果我能在 xml 解析方面获得一些帮助,那么我就可以处理其余的事情。

将非常感谢任何帮助!

谢谢和问候!

我的 xml 文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<bible>
 <testament name="Old Testament">
  <book name="Genesis">
   <chapter id="Genesis 1"></chapter>
   <chapter id="Genesis 2"></chapter>
  </book>
  <book name="Exodus">
   <chapter id="Exodus 1"></chapter>
   <chapter id="Exodus 2"></chapter>
  </book>
 </testament>
 <testament name="New Testament">
  <book name="Matthew">
   <chapter id="Matthew 1"></chapter>
   <chapter id="Matthew 2"></chapter>
  </book>
  <book name="Revelation">
   <chapter id="Revelation 1"></chapter>
   <chapter id="Revelation 2"></chapter>
  </book>
 </testament>
</bible>

//  Bible.h
#import <Foundation/Foundation.h>

@interface Bible : NSObject {
 NSMutableArray *bible;
 NSMutableArray *testament;
 NSMutableArray *book;
 NSString *chapterID;

}

@property (nonatomic, retain)NSMutableArray *bible;
@property (nonatomic, retain)NSMutableArray *testament;
@property (nonatomic, retain)NSMutableArray *book;
@property (nonatomic, retain)NSString *chapterID;

@end

//  Bible.m

#import "Bible.h"


@implementation Bible

@synthesize bible;
@synthesize testament;
@synthesize book;
@synthesize chapterID;

- (void) dealloc {
 [bible release];
 [testament release];
 [book release];
 [chapterID release];
 [super dealloc];
}

@end

//
//  XMLParser.h
//  BibleXML
//

#import <Foundation/Foundation.h>
#import "Bible.h"

@protocol NSXMLParserDelegate;

@class BibleXMLAppDelegate, Bible;

@interface XMLParser : NSObject <NSXMLParserDelegate> {


 NSMutableString *currentElementValue;

 BibleXMLAppDelegate *appDelegate;
 Bible *theBible;

}

- (XMLParser *) initXMLParser;

@end

//
//  XMLParser.m

#import "XMLParser.h"
#import "BibleXMLAppDelegate.h"
#import "Bible.h"


@implementation XMLParser

- (XMLParser *) initXMLParser {

 [super init];

 appDelegate = (BibleXMLAppDelegate *) [[UIApplication sharedApplication] delegate];
 return self;
}

- (void)parserDidStartDocument:(NSXMLParser *)parser{ 
 NSLog(@"found file and started parsing");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
 attributes:(NSDictionary *)attributeDict {
 if([elementName isEqualToString:@"bible"]) {
  NSLog(@"Found element: %@", elementName);
  appDelegate.bible = [[NSMutableArray alloc] init];
 }

 else if([elementName isEqualToString:@"testament"]) {

  theBible = [[Bible alloc] init];
  //Extract the attribute here.
  theBible.testament = [attributeDict valueForKey:@"name"];
  NSLog(@"Testament: %@", theBible.testament);
  return;
 }

 else if ([elementName isEqualToString:@"book"])
 {
  theBible.book = [attributeDict valueForKey:@"name"];
  NSLog(@"Book: %@", theBible.book);
  return;
 }

 else if([elementName isEqualToString:@"chapter"]) 
 {
  theBible.chapterID =[attributeDict objectForKey:@"id"];
  NSLog(@"Chapter: %@", theBible.chapterID);
  return;
 } 
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 if([elementName isEqualToString:@"bible"]){
   return;
 } 

}


- (void) dealloc {
 [theBible release];
 [currentElementValue release];
 [super dealloc];
}

@end

以下是调试器控制台的输出:

2010-12-08 19:53:10.101 BibleXML[25641:207] found file and started parsing
2010-12-08 19:53:10.102 BibleXML[25641:207] Found element: bible
2010-12-08 19:53:10.103 BibleXML[25641:207] Testament: Old Testament
2010-12-08 19:53:10.103 BibleXML[25641:207] Book: Genesis
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 1
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 2
2010-12-08 19:53:10.105 BibleXML[25641:207] Book: Exodus
2010-12-08 19:53:10.105 BibleXML[25641:207] Chapter: Exodus 1
2010-12-08 19:53:10.106 BibleXML[25641:207] Chapter: Exodus 2
2010-12-08 19:53:10.107 BibleXML[25641:207] Testament: New Testament
2010-12-08 19:53:10.107 BibleXML[25641:207] Book: Matthew
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 1
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 2
2010-12-08 19:53:10.109 BibleXML[25641:207] Book: Revelation
2010-12-08 19:53:10.109 BibleXML[25641:207] Chapter: Revelation 1
2010-12-08 19:53:10.110 BibleXML[25641:207] Chapter: Revelation 2
2010-12-08 19:53:10.110 BibleXML[25641:207] No Errors

I need help with parsing a xml file. My problem is I don't know how to implement the didEndElement delegate.
What I want is that I will have 2 cells where Old Testament and New Testament will be displayed and then the Books of the Bible and the the chapters.
If I can just get some help with the xml parsing the rest I can manage.

Will be very grateful for any help!

Thanks and regards!

My xml file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<bible>
 <testament name="Old Testament">
  <book name="Genesis">
   <chapter id="Genesis 1"></chapter>
   <chapter id="Genesis 2"></chapter>
  </book>
  <book name="Exodus">
   <chapter id="Exodus 1"></chapter>
   <chapter id="Exodus 2"></chapter>
  </book>
 </testament>
 <testament name="New Testament">
  <book name="Matthew">
   <chapter id="Matthew 1"></chapter>
   <chapter id="Matthew 2"></chapter>
  </book>
  <book name="Revelation">
   <chapter id="Revelation 1"></chapter>
   <chapter id="Revelation 2"></chapter>
  </book>
 </testament>
</bible>

//  Bible.h
#import <Foundation/Foundation.h>

@interface Bible : NSObject {
 NSMutableArray *bible;
 NSMutableArray *testament;
 NSMutableArray *book;
 NSString *chapterID;

}

@property (nonatomic, retain)NSMutableArray *bible;
@property (nonatomic, retain)NSMutableArray *testament;
@property (nonatomic, retain)NSMutableArray *book;
@property (nonatomic, retain)NSString *chapterID;

@end

//  Bible.m

#import "Bible.h"


@implementation Bible

@synthesize bible;
@synthesize testament;
@synthesize book;
@synthesize chapterID;

- (void) dealloc {
 [bible release];
 [testament release];
 [book release];
 [chapterID release];
 [super dealloc];
}

@end

//
//  XMLParser.h
//  BibleXML
//

#import <Foundation/Foundation.h>
#import "Bible.h"

@protocol NSXMLParserDelegate;

@class BibleXMLAppDelegate, Bible;

@interface XMLParser : NSObject <NSXMLParserDelegate> {


 NSMutableString *currentElementValue;

 BibleXMLAppDelegate *appDelegate;
 Bible *theBible;

}

- (XMLParser *) initXMLParser;

@end

//
//  XMLParser.m

#import "XMLParser.h"
#import "BibleXMLAppDelegate.h"
#import "Bible.h"


@implementation XMLParser

- (XMLParser *) initXMLParser {

 [super init];

 appDelegate = (BibleXMLAppDelegate *) [[UIApplication sharedApplication] delegate];
 return self;
}

- (void)parserDidStartDocument:(NSXMLParser *)parser{ 
 NSLog(@"found file and started parsing");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
 attributes:(NSDictionary *)attributeDict {
 if([elementName isEqualToString:@"bible"]) {
  NSLog(@"Found element: %@", elementName);
  appDelegate.bible = [[NSMutableArray alloc] init];
 }

 else if([elementName isEqualToString:@"testament"]) {

  theBible = [[Bible alloc] init];
  //Extract the attribute here.
  theBible.testament = [attributeDict valueForKey:@"name"];
  NSLog(@"Testament: %@", theBible.testament);
  return;
 }

 else if ([elementName isEqualToString:@"book"])
 {
  theBible.book = [attributeDict valueForKey:@"name"];
  NSLog(@"Book: %@", theBible.book);
  return;
 }

 else if([elementName isEqualToString:@"chapter"]) 
 {
  theBible.chapterID =[attributeDict objectForKey:@"id"];
  NSLog(@"Chapter: %@", theBible.chapterID);
  return;
 } 
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 if([elementName isEqualToString:@"bible"]){
   return;
 } 

}


- (void) dealloc {
 [theBible release];
 [currentElementValue release];
 [super dealloc];
}

@end

Following is the output from the debugger console:

2010-12-08 19:53:10.101 BibleXML[25641:207] found file and started parsing
2010-12-08 19:53:10.102 BibleXML[25641:207] Found element: bible
2010-12-08 19:53:10.103 BibleXML[25641:207] Testament: Old Testament
2010-12-08 19:53:10.103 BibleXML[25641:207] Book: Genesis
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 1
2010-12-08 19:53:10.104 BibleXML[25641:207] Chapter: Genesis 2
2010-12-08 19:53:10.105 BibleXML[25641:207] Book: Exodus
2010-12-08 19:53:10.105 BibleXML[25641:207] Chapter: Exodus 1
2010-12-08 19:53:10.106 BibleXML[25641:207] Chapter: Exodus 2
2010-12-08 19:53:10.107 BibleXML[25641:207] Testament: New Testament
2010-12-08 19:53:10.107 BibleXML[25641:207] Book: Matthew
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 1
2010-12-08 19:53:10.108 BibleXML[25641:207] Chapter: Matthew 2
2010-12-08 19:53:10.109 BibleXML[25641:207] Book: Revelation
2010-12-08 19:53:10.109 BibleXML[25641:207] Chapter: Revelation 1
2010-12-08 19:53:10.110 BibleXML[25641:207] Chapter: Revelation 2
2010-12-08 19:53:10.110 BibleXML[25641:207] No Errors

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明明#如月 2024-10-13 16:23:58

你已经在解析它了。在 didEndElement: 调用中,只需对元素执行任何您想要执行的操作即可。由于您的 XML 不包含任何包装字符串(您没有使用 foundCharacters:),因此您所要做的就是响应 didStartElement:didEndElement:相应地。如果您需要捕获属性或分配新的数据结构来保存可能的子级,请在 didStartElement: 中执行此操作。如果您需要将对象保存到集合中或以某种方式完成特定元素的处理,请在 didEndElement: 中执行此操作。

这个问题实际上并不是关于解析,而是关于您想要响应解析而制定的任何逻辑。

编辑以响应下面的评论:

我通常会执行以下操作以在解析期间保存对象:在我的界面中,我声明需要将对象保存到的集合以及用于保存任何内容的临时对象在将其添加到集合之前我需要的数据,如下所示

@interface MyClass : NSObject <NSXMLParserDelegate>{
    NSMutableArray *collection_;
    SomeObject *tempObject_;
}
@end

在实现中,我操作这两个对象,通常在 didStartDocument:、didStartElement:didEndElement:< /code>,如下所示:

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    collection_ = [[NSMutableArray alloc] init];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    //if your object is tied to a tag that wraps text (delivered in foundCharacters:), initialize it here
    tempObject_ = [[SomeObject alloc] init];
    //maybe you need the attributes....
    tempObject_.someProperty = [attributes objectForKey:@"attribute-name"];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    //when the tag ends, you can save it off into the collection
    [collection_ addObject:tempObject_];
    [tempObject_ release];
    tempObject_ = nil;
}

然后对集合对象执行您想要的操作。确保处理内存事务,例如释放集合对象或其他内容。我通常使用类似委托回调(我自己设计的)之类的东西来将集合获取到模型,以便在逻辑上将解析与模型分开。

You're already parsing it. In the didEndElement: call, just do whatever you want to do with the element. Since your XML doesn't contain any wrapped strings (you're not using foundCharacters:), all you have to do is respond to didStartElement: and didEndElement: accordingly. If you need to capture attributes or allocate a new data structure to hold possible children, do it in didStartElement:. If you need to save off objects into collections or somehow finish processing of a particular element, do it in didEndElement:.

This question isn't really about parsing, it's about whatever logic you want to enact in response to parsing.

Edit in response to comment below:

I typically do the following to save off objects during parsing: in my interface, I declare the collection I need to save objects into and a temporary object that I used to hold whatever data I need to before adding it to the collection, like this

@interface MyClass : NSObject <NSXMLParserDelegate>{
    NSMutableArray *collection_;
    SomeObject *tempObject_;
}
@end

In the implementation I manipulate these two objects, typically in didStartDocument:, didStartElement: and didEndElement:, like so:

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    collection_ = [[NSMutableArray alloc] init];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    //if your object is tied to a tag that wraps text (delivered in foundCharacters:), initialize it here
    tempObject_ = [[SomeObject alloc] init];
    //maybe you need the attributes....
    tempObject_.someProperty = [attributes objectForKey:@"attribute-name"];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    //when the tag ends, you can save it off into the collection
    [collection_ addObject:tempObject_];
    [tempObject_ release];
    tempObject_ = nil;
}

Then do what you will with the collection object. Make sure you handle memory things, like releasing the collection object or whatever. I usually use something like a delegate callback (of my own devising) to get the collection to the model, in order to logically separate parsing from the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文