Как проанализировать несколько тегов XML с помощью NSXMLParser - PullRequest
2 голосов
/ 07 ноября 2010

Я анализирую XML-файл и заполняю табличное представление. XML имеет такой формат:

<article>
  <title>Title 1</title>
  <last-modified>MM/DD/YYY</last-modified>
</article>
...

В настоящее время он работает, используя NSMutableString для сбора всех заголовков статей и добавления строк в методе - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string. Затем в соответствующее время я добавляю articleTitle к NSMutableArray, который содержит все заголовки статей, и заполняю таблицу из массива, как и следовало ожидать.

Однако теперь я хочу переключиться на использование ячейки табличного представления с субтитрами (я хочу поставить дату последнего изменения как detailTextLabel, а заголовок - как textLabel). Учитывая то, как синтаксический анализ разбивается на несколько методов (например, методы 2 parser и метод foundCharacters), я не уверен, как мне следует собирать данные и заполнять таблицу из этих данных.

Какой лучший подход к этому? Могу ли я как-то просто заполнить NSDictionary или что-то еще, и просто получить элементы по ключу при построении ячеек таблицы?

Кажется, я не могу найти лучший способ справиться с этим.

Заранее спасибо!

Ответы [ 3 ]

5 голосов
/ 07 ноября 2010

Вы можете использовать парсер DOM, если хотите, и это может немного облегчить вашу жизнь, но если по какой-то причине вы хотите придерживаться NSXMLParser, продолжайте читать.

Вы хотите, чтобы объект, который вы предоставляете синтаксическому анализатору в качестве вашего делегата (то, что реализует NSXMLParserDelegate), в основном накапливает данные при передаче данных.

ВАЖНАЯ ИНФОРМАЦИЯ, ЧАСТО ОБНАРУЖЕННАЯ: Для «содержимого» различных тегов вы можете фактически получить несколько вызовов на parser:foundCharacters:. Нет абсолютно никакого требования, чтобы парсер передавал все это вам сразу. Если бы он захотел, он мог бы посылать вам по одному символу за раз, и вы должны были бы правильно с ним справиться.

Предполагается, что следующие ivars:

NSMutableArray articles_;
NSMutableString currentCharacters_;
Article currentArticle_; // Article has title and lastModified properties.

А вот пример того, как делегат может реализовать несколько релевантных сообщений (следующий код, очевидно, не обрабатывает ошибки):

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"article"]) {
        NSAssert(currentArticle_ == nil, @"Uh oh! Bad XML!");
        currentArticle_ = [[Article alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"title"]) {
        NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!");
        currentCharacters_ = [[NSMutableString alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"last-modified"]) {
        NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!");
        currentCharacters_ = [[NSMutableString alloc] init];
        return;
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"article"]) {
        [articles_ addObject:currentArticle_];
        [currentArticle_ release], currentArticle_ = nil;
        return;
    }
    if ([elementName isEqualToString:@"title"]) {
        currentArticle_.title = currentCharacters_;
        [currentCharacters_ release], currentCharacters_ = nil;
        return;
    }
    if ([elementName isEqualToString:@"last-modified"]) {
        [currentArticle_ setLastModifiedWithString:currentCharacters_];
        [currentCharacters_ release], currentCharacters_ = nil;
        return;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [currentCharacters_ appendString:string];
}
0 голосов
/ 07 ноября 2010

Я использую DOM Parser, он чище и проще, если вы не анализируете много данных .. рекомендую Google GDATA

здесь есть StackOverflow Questio n на нем

NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
if (doc == nil) { return nil; }

// get number of hits
GDataXMLElement * article = [[doc nodesForXPath:@"//article" error:nil] objectAtIndex:0];

// title
NSLog([[[entry elementsForName:@"title"] objectAtIndex:0] stringValue]], nil);

// last-modified
NSLog([[[entry elementsForName:@"last-modified"] objectAtIndex:0] stringValue]], nil);
0 голосов
/ 07 ноября 2010

Вы можете прочитать официальное Event-Driven XML Programming Guide и учебник

Также я могу предложить вместо touchXML NSXMLParser

...