Простой и краткий пример рабочего стола Cocoa NSXMLParser? - PullRequest
1 голос
/ 28 сентября 2011

Я хотел бы просмотреть элементы файла и, когда выйдет один конкретный элемент, вывести содержимое между тегом.

Я пытался следовать примеру в Mac Dev под названием Событийно-управляемое XML-программирование , но он просто не очень хорошо закончен. Он говорит, чтобы убедиться, что я кодирую делегатов, но он никогда не показывает пример. Я просто хочу увидеть простой пример, где:

  • Предполагается, что файл является хорошим XML-файлом.
  • Его путь - это URL (или строка).
  • Объясняется, как делегат взаимодействует с синтаксическим анализатором.

Многие учебники по Какао, кажется, почти учат вас обходить классы делегатов и создавать свои собственные функции IBAction, поэтому мне не хватает обучения, которое я думаю о том, как правильно использовать делегатов. В примере не ясно, должен ли я собирать делегаты в классе делегатов или хранить их в классе с помощью синтаксического анализатора.

Ответы [ 3 ]

3 голосов
/ 28 сентября 2011

Это основано на том, что я изначально написал для Вырежьте часть длинной строки 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 
1 голос
/ 28 сентября 2011

Если щелкнуть ссылку «Далее» на этой странице и перейти к «Обработка элементов и атрибутов XML», это даст вам пример того, как кодировать делегатов.

Apple предоставляет пример Mac в ImageMap .

Нет разницы между NSXMLParser на Mac и iPhone, поэтому чтение примера iPhone не должно быть проблемой.

0 голосов
/ 28 сентября 2011

Вот пример использования 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
}
...