简单简洁的桌面Cocoa NSXMLParser例子?

发布于 2024-12-07 00:50:35 字数 481 浏览 0 评论 0原文

我想查看文件的元素,当出现一个特定元素时,输出标签之间的内容。

我尝试遵循 Mac Dev 中标题为 事件驱动的 XML 编程,但它只是没有完成得很清楚。它说要确保我对代表进行编码,但它从未显示示例。我只想看一个简单的示例,其中:

  • 该文件被假定为一个好的 xml 文件。
  • 它的路径是一个 URL(或字符串)。
  • 解释了委托与解析器交互的方式。

Cocoa 的许多教程似乎几乎都是教您绕过委托类并创建自己的 IBAction 函数,因此我错过了我认为如何正确使用委托的培训。在示例中不清楚我是否应该在委托类中构建委托,或者将它们保留在带有解析器的类中。

I would like to look through the elements of a file and when one specific element comes out, output the contents in between the tag.

I tried to follow the example in the Mac Dev entitled Event Driven XML Programming, but it just doesn't finish very clearly. It says to make sure I code the delegates, but it never shows an example. I just want to see a simple example where:

  • The file is assumed to be a good xml file.
  • Its path is a URL (or string).
  • The way the delegate interacts with the parser is explained.

Many tutorials for Cocoa seem to almost teach you to circumvent the delegate classes and make your own IBAction functions so I'm missing the training I think on how to use the delegates properly. Its not clear in the example if I'm supposed to build the delegates in the delegate class or keep them in the class with the parser.

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

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

发布评论

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

评论(3

萌辣 2024-12-14 00:50:35

这是基于我最初为 剪掉长的一部分NSString。我将 NSXMLParserDelegate 代码从该 iOS 项目复制到 OS X 项目中。它从网页中的特定对象获取文本。

.h 文件:

@interface so7576593AppDelegate : NSObject <NSApplicationDelegate, NSXMLParserDelegate> {
    NSWindow *window;
    IBOutlet NSTextField *textField;

    NSMutableString *divCharacters;
    BOOL captureCharacters; 
}

@property (assign) IBOutlet NSWindow *window;

@end

.m 文件:

#import "so7576593AppDelegate.h"

@implementation so7576593AppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    captureCharacters = NO;
    NSURL *theURL = [NSURL URLWithString:@"http://maxnerios.yolasite.com/"];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:theURL];
    [parser setDelegate:self];
    [parser parse];
    [parser release];

}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqual:@"div"] && [[attributeDict objectForKey:@"id"] isEqual:@"I3_sys_txt"]) {
        captureCharacters = YES;
        divCharacters = [[NSMutableString alloc] initWithCapacity:500];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (captureCharacters) {
        //from parser:foundCharacters: docs:
        //The parser object may send the delegate several parser:foundCharacters: messages to report the characters of an element. 
        //Because string may be only part of the total character content for the current element, you should append it to the current 
        //accumulation of characters until the element changes.
        [divCharacters appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if (captureCharacters) {
        captureCharacters = NO;
        [textField setStringValue:divCharacters];
        [divCharacters release];
    }
}

@end 

This is based on something I originally wrote for Cut out a part of a long NSString. I copied the NSXMLParserDelegate code from that iOS project into an OS X project. It gets the text from a specific object in a web page.

.h file:

@interface so7576593AppDelegate : NSObject <NSApplicationDelegate, NSXMLParserDelegate> {
    NSWindow *window;
    IBOutlet NSTextField *textField;

    NSMutableString *divCharacters;
    BOOL captureCharacters; 
}

@property (assign) IBOutlet NSWindow *window;

@end

.m file:

#import "so7576593AppDelegate.h"

@implementation so7576593AppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    captureCharacters = NO;
    NSURL *theURL = [NSURL URLWithString:@"http://maxnerios.yolasite.com/"];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:theURL];
    [parser setDelegate:self];
    [parser parse];
    [parser release];

}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqual:@"div"] && [[attributeDict objectForKey:@"id"] isEqual:@"I3_sys_txt"]) {
        captureCharacters = YES;
        divCharacters = [[NSMutableString alloc] initWithCapacity:500];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (captureCharacters) {
        //from parser:foundCharacters: docs:
        //The parser object may send the delegate several parser:foundCharacters: messages to report the characters of an element. 
        //Because string may be only part of the total character content for the current element, you should append it to the current 
        //accumulation of characters until the element changes.
        [divCharacters appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if (captureCharacters) {
        captureCharacters = NO;
        [textField setStringValue:divCharacters];
        [divCharacters release];
    }
}

@end 
人│生佛魔见 2024-12-14 00:50:35

如果单击该页面上的“下一步”链接并转到“处理 XML 元素和属性”,它将为您提供如何对委托进行编码的示例。

Apple 在 ImageMap 中提供了 Mac 示例。

Mac 和 iPhone 上的 NSXMLParser 之间没有区别,因此阅读 iPhone 示例应该不成问题。

If you click the "Next" link on that page and go onto "Handling XML Elements and Attributes" it will give you an example of how to code the delegates.

Apple provides a Mac example in ImageMap.

There's no difference between NSXMLParser on Mac and iPhone, so reading an iPhone example shouldn't be a problem.

屋檐 2024-12-14 00:50:35

下面是在自定义类中使用 NSXMLParser 的示例,该类接收要查找的标签字符串和 xml NSData:

JHXMLParser.h:

@protocol JHXMLParserDelegate <NSObject>
@optional
- (void)acceptParsedData:(NSMutableArray *)parsedData withIdent:(NSString *)ident;
- (void)acceptParsedDebugData:(NSMutableArray *)parsedData withIdent:(NSString *)ident;

@end

@class JHKeyValuePair;

@interface JHXMLParser : NSObject <NSXMLParserDelegate> {
    NSString *ident;

    @private
    id _delegate;
    NSMutableArray *_parsedData;
    NSString *_key;
    NSData *_rawData;
    NSXMLParser *_dataParser;
    NSString *_previousTag;
    NSString *_currentTag;
}

@property (retain, nonatomic) NSString *ident;

- (id)initWithKeyValuePair:(JHKeyValuePair *)kvPair;
- (id)initWithKey:(NSString *)Key andData:(NSData *)data;
// delegate management. The delegate is not retained.
- (id <JHXMLParserDelegate>)delegate;
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate;
- (BOOL)start;

@end

和 JHXMLParser.m:

#import "JHKeyValuePair.h"
#import "JHXMLParser.h"

@implementation JHXMLParser

@synthesize ident;

- (id)init {
    if ((self = [super init])) {
        ident = [[NSString alloc] init];
    }
    return self;
}

- (id)initWithKeyValuePair:(JHKeyValuePair *)kvPair {
    if ((self = [self init])) {
        _key = [kvPair key];
        _rawData = [kvPair value];
        _dataParser = [[NSXMLParser alloc] initWithData:_rawData];
        _dataParser.delegate = self;
    }
    return self;
}

- (id)initWithKey:(NSString *)key andData:(NSData *)data {
    if ((self = [self init])) {
        _key = key;
        _rawData = data;
        _dataParser = [[NSXMLParser alloc] initWithData:_rawData];
        _dataParser.delegate = self;
    }
    return self;
}

- (id <JHXMLParserDelegate>)delegate {
    id <JHXMLParserDelegate> d = nil;
    if (_delegate) {
        d = _delegate;
    }
    return d;
}
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate {
    _delegate = delegate;
}

- (BOOL)start {
    return [_dataParser parse];
}

- (void)dealloc {
    [_parsedData release];
    [_rawData release];
    [super dealloc];
}

#pragma mark - NSXMLParser Delegate

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

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    _currentTag = elementName;
    if ([elementName isEqualToString:_key]) {
        NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];
        [_parsedData addObject:tmpDict];
        [tmpDict release];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (![_previousTag isEqualToString:_currentTag]) {
        [[_parsedData lastObject] setObject:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
                                     forKey:_currentTag];
    } else {
        [[_parsedData lastObject] setObject:[NSString stringWithFormat:@"%@%@",[[_parsedData lastObject] objectForKey:_currentTag], [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]] 
                                     forKey:_currentTag];
    }
    if (_previousTag) {
        [_previousTag release];
        _previousTag = nil;
    }
    _previousTag = [[NSString alloc] initWithFormat:@"%@", _currentTag];
    [pool drain];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (![_previousTag isEqualToString:elementName]) {
        [[_parsedData lastObject] setObject:@"" forKey:elementName];
    } else {
        if (_previousTag) {
            [_previousTag release];
            _previousTag = nil;
        }
        _previousTag = [[NSString alloc] initWithFormat:@""];
    }
    [pool drain];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:_parsedData withIdent:ident];
    } else if ([_delegate respondsToSelector:@selector(acceptParsedDebugData:withIdent:)]) {
        [_delegate acceptParsedDebugData:_parsedData withIdent:ident];
    }
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
#ifdef DEBUG
    DEBUGLOG(@"Parser ERROR Occurred: %@", self.ident);
    DEBUGLOG(@"ERROR: %@", parseError);
#endif
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:_parsedData withIdent:ident];
    } else if ([_delegate respondsToSelector:@selector(acceptParsedDebugData:withIdent:)]) {
        [_delegate acceptParsedDebugData:_parsedData withIdent:ident];
    }
}

@end

如下使用:

parser = [[[JHXMLParser alloc] initWithKey:@"INFO" andData:connectData] autorelease];
parser.ident = @"INFO";
parser.delegate = self;
[parser start];

然后实现委托方法:

- (void)acceptParsedData:(NSMutableArray *)parsedData withIdent:(NSString *)ident {
    // do stuff here with the parsed data
}

Here is an example of using an NSXMLParser in a custom class that takes in a string of the tag to look for and the xml NSData:

JHXMLParser.h:

@protocol JHXMLParserDelegate <NSObject>
@optional
- (void)acceptParsedData:(NSMutableArray *)parsedData withIdent:(NSString *)ident;
- (void)acceptParsedDebugData:(NSMutableArray *)parsedData withIdent:(NSString *)ident;

@end

@class JHKeyValuePair;

@interface JHXMLParser : NSObject <NSXMLParserDelegate> {
    NSString *ident;

    @private
    id _delegate;
    NSMutableArray *_parsedData;
    NSString *_key;
    NSData *_rawData;
    NSXMLParser *_dataParser;
    NSString *_previousTag;
    NSString *_currentTag;
}

@property (retain, nonatomic) NSString *ident;

- (id)initWithKeyValuePair:(JHKeyValuePair *)kvPair;
- (id)initWithKey:(NSString *)Key andData:(NSData *)data;
// delegate management. The delegate is not retained.
- (id <JHXMLParserDelegate>)delegate;
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate;
- (BOOL)start;

@end

And the JHXMLParser.m:

#import "JHKeyValuePair.h"
#import "JHXMLParser.h"

@implementation JHXMLParser

@synthesize ident;

- (id)init {
    if ((self = [super init])) {
        ident = [[NSString alloc] init];
    }
    return self;
}

- (id)initWithKeyValuePair:(JHKeyValuePair *)kvPair {
    if ((self = [self init])) {
        _key = [kvPair key];
        _rawData = [kvPair value];
        _dataParser = [[NSXMLParser alloc] initWithData:_rawData];
        _dataParser.delegate = self;
    }
    return self;
}

- (id)initWithKey:(NSString *)key andData:(NSData *)data {
    if ((self = [self init])) {
        _key = key;
        _rawData = data;
        _dataParser = [[NSXMLParser alloc] initWithData:_rawData];
        _dataParser.delegate = self;
    }
    return self;
}

- (id <JHXMLParserDelegate>)delegate {
    id <JHXMLParserDelegate> d = nil;
    if (_delegate) {
        d = _delegate;
    }
    return d;
}
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate {
    _delegate = delegate;
}

- (BOOL)start {
    return [_dataParser parse];
}

- (void)dealloc {
    [_parsedData release];
    [_rawData release];
    [super dealloc];
}

#pragma mark - NSXMLParser Delegate

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

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    _currentTag = elementName;
    if ([elementName isEqualToString:_key]) {
        NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];
        [_parsedData addObject:tmpDict];
        [tmpDict release];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (![_previousTag isEqualToString:_currentTag]) {
        [[_parsedData lastObject] setObject:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
                                     forKey:_currentTag];
    } else {
        [[_parsedData lastObject] setObject:[NSString stringWithFormat:@"%@%@",[[_parsedData lastObject] objectForKey:_currentTag], [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]] 
                                     forKey:_currentTag];
    }
    if (_previousTag) {
        [_previousTag release];
        _previousTag = nil;
    }
    _previousTag = [[NSString alloc] initWithFormat:@"%@", _currentTag];
    [pool drain];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (![_previousTag isEqualToString:elementName]) {
        [[_parsedData lastObject] setObject:@"" forKey:elementName];
    } else {
        if (_previousTag) {
            [_previousTag release];
            _previousTag = nil;
        }
        _previousTag = [[NSString alloc] initWithFormat:@""];
    }
    [pool drain];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:_parsedData withIdent:ident];
    } else if ([_delegate respondsToSelector:@selector(acceptParsedDebugData:withIdent:)]) {
        [_delegate acceptParsedDebugData:_parsedData withIdent:ident];
    }
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
#ifdef DEBUG
    DEBUGLOG(@"Parser ERROR Occurred: %@", self.ident);
    DEBUGLOG(@"ERROR: %@", parseError);
#endif
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:_parsedData withIdent:ident];
    } else if ([_delegate respondsToSelector:@selector(acceptParsedDebugData:withIdent:)]) {
        [_delegate acceptParsedDebugData:_parsedData withIdent:ident];
    }
}

@end

Used like so:

parser = [[[JHXMLParser alloc] initWithKey:@"INFO" andData:connectData] autorelease];
parser.ident = @"INFO";
parser.delegate = self;
[parser start];

Then implement the delegate method:

- (void)acceptParsedData:(NSMutableArray *)parsedData withIdent:(NSString *)ident {
    // do stuff here with the parsed data
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文