Cocoa: синтаксический анализ XML

#xml #cocoa #parsing

#xml #cocoa #синтаксический анализ

Вопрос:

Я пытаюсь сохранить некоторые XML-данные в словаре, но по какой-то причине, когда я запускаю методы для моего XMLParser, массив и данные словаря, которые я пытаюсь установить, не устанавливаются. Данные XML есть, я могу их зарегистрировать и увидеть имяэлемЕнта и строковые значения, но, похоже, я не могу подключить их к массиву или словарю. Не уверен, что я делаю неправильно.

Вот мой файл .h:

 #import <Cocoa/Cocoa.h>

@interface AppController : NSObject {


    IBOutlet id txtSpeechBox;
    IBOutlet id btnSpeechBtn;

    NSSpeechSynthesizer* synth;
    NSURL* urlToPass;
    NSXMLParser* dataParser;

    NSMutableDictionary* dataDict;
    NSMutableArray* dataKeys;

    NSString* currentKey;
    NSMutableString* currentStringValue;

}

- (void) parseXMLFile : (NSURL *) url;
- (void) speakJasper; 
  

и мой файл .m:

 #import "AppController.h"

@implementation AppController
- (void) awakeFromNib { 
//set up our speech synth
synth = [[NSSpeechSynthesizer alloc] init];

//go and grab the weather data
urlToPass = [[NSURL alloc] initWithString:@"http://www.weather.gov/xml/current_obs/KPTW.xml"];

NSData *data = [NSData dataWithContentsOfURL: urlToPass];
NSString *weatherData = [[NSString alloc] initWithData:data encoding:NSMacOSRomanStringEncoding];

[self parseXMLFile:urlToPass];
//NSLog(weatherData);

dataDict =  [[NSMutableDictionary alloc] init];
dataKeys = [[NSMutableArray alloc] init];
[dataKeys addObject:@"test line"];
currentKey = [[NSString alloc] init];

[dataDict, dataKeys release];
}

- (void) parseXMLFile : (NSURL *) url {
BOOL success;
if (dataParser) // addressParser is an NSXMLParser instance variable
        [dataParser release];
        dataParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
        [dataParser setDelegate:self];
        [dataParser setShouldResolveExternalEntities:YES];
        success = [dataParser parse]; // return value not used
// if not successful, delegate is informed of error
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentKey = nil;
[currentStringValue release];
currentStringValue = nil;

currentKey = [NSString stringWithFormat: @"%@", elementName];
return;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentStringValue){
    currentStringValue = [[NSMutableString alloc] init];
}
[currentStringValue appendString:string];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
[dataKeys addObject:currentKey];
[dataDict setObject:currentStringValue forKey:currentKey];
[dataKeys addObject:@"test"];
[self speakJasper];
}

- (void) speakJasper { 
//set up a string for what jasper will say
NSMutableString* speakString = [[NSMutableString alloc] init];
speakString = @"Good morning, the current weather is";

//start looping through the dataKeys array to get the dataDict keys, take that value and add to speak string
for(int d=0; d<dataKeys.count; d  ) { 
    NSString* thisDataKey = [dataKeys objectAtIndex:d];
    if  (thisDataKey == @"weather") { 
        NSString* thisDataValue = [dataDict objectForKey:thisDataKey];
        [speakString appendString:thisDataValue];
    }
}
NSLog(@"%i", dataKeys.count);
//[synth startSpeakingString:speakString];
}
 @end
  

Комментарии:

1. «Не уверен, что я делаю неправильно» — это не вопрос. Проверьте на codereview.stackexchange.com если вы хотите, чтобы кто-то прочесал ваш код.

Ответ №1:

Вы инициализируете свой словарь и ключи ПОСЛЕ того, как XML-файл уже был проанализирован:

 [self parseXMLFile:urlToPass];
dataDict = [[NSMutableDictionary alloc] init];
dataKeys = [[NSMutableArray alloc] init];
  

таким образом, dataDict и DataKeys равны нулю, поскольку вызываются didStartElement:, foundChars: и endElement: .

Переместите эту первую строку ниже следующих двух, и вы получите свои данные.

Комментарии:

1. Спасибо за подсказку, Стив, вот что ты получаешь за кодирование воскресным утром…