diff --git a/README b/README index e69de29..e13a837 100644 --- a/README +++ b/README @@ -0,0 +1,7 @@ +The key ideas: + + 1 XML elements map to key names in the dictionary + 2 Each element corresponds to a child dictionary + 3 Attribute key-value pairs are added to the element’s child dictionary + 4 Strings from text nodes are assigned to the child dictionary’s “text” key + 5 If an element name is encountered multiple times, the value of the element is set to an array of children dictionaries diff --git a/XMLReader.h b/XMLReader.h index 3145071..9a4ec7a 100644 --- a/XMLReader.h +++ b/XMLReader.h @@ -6,8 +6,8 @@ #import -@interface XMLReader : NSObject -{ +@interface XMLReader : NSObject { + NSMutableArray *dictionaryStack; NSMutableString *textInProgress; NSError **errorPointer; diff --git a/XMLReader.m b/XMLReader.m index 6820ee6..eea1eed 100644 --- a/XMLReader.m +++ b/XMLReader.m @@ -19,16 +19,16 @@ @implementation XMLReader #pragma mark - #pragma mark Public methods -+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error -{ ++ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error { + XMLReader *reader = [[XMLReader alloc] initWithError:error]; NSDictionary *rootDictionary = [reader objectWithData:data]; [reader release]; return rootDictionary; } -+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error -{ ++ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error { + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; return [XMLReader dictionaryForXMLData:data error:error]; } @@ -36,24 +36,24 @@ + (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)er #pragma mark - #pragma mark Parsing -- (id)initWithError:(NSError **)error -{ - if (self = [super init]) - { +- (id)initWithError:(NSError **)error { + + if (self == [super init]) { + errorPointer = error; } return self; } -- (void)dealloc -{ +- (void)dealloc { + [dictionaryStack release]; [textInProgress release]; [super dealloc]; } -- (NSDictionary *)objectWithData:(NSData *)data -{ +- (NSDictionary *)objectWithData:(NSData *)data { + // Clear out any old data [dictionaryStack release]; [textInProgress release]; @@ -70,20 +70,23 @@ - (NSDictionary *)objectWithData:(NSData *)data BOOL success = [parser parse]; // Return the stack's root dictionary on success - if (success) - { - NSDictionary *resultDict = [dictionaryStack objectAtIndex:0]; + if (success){ + + NSDictionary *resultDict = [dictionaryStack objectAtIndex:0]; + + [parser release]; return resultDict; } - + + [parser release]; return nil; } #pragma mark - #pragma mark NSXMLParserDelegate methods -- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict -{ +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { + // Get the dictionary for the current level in the stack NSMutableDictionary *parentDict = [dictionaryStack lastObject]; @@ -93,8 +96,7 @@ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName nam // If there's already an item for this key, it means we need to create an array id existingValue = [parentDict objectForKey:elementName]; - if (existingValue) - { + if (existingValue) { NSMutableArray *array = nil; if ([existingValue isKindOfClass:[NSMutableArray class]]) { @@ -114,8 +116,8 @@ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName nam // Add the new child dictionary to the array [array addObject:childDict]; } - else - { + else { + // No existing value, so update the dictionary [parentDict setObject:childDict forKey:elementName]; } @@ -124,14 +126,14 @@ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName nam [dictionaryStack addObject:childDict]; } -- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName -{ +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { + // Update the parent dict with text info NSMutableDictionary *dictInProgress = [dictionaryStack lastObject]; // Set the text property - if ([textInProgress length] > 0) - { + if ([textInProgress length] > 0) { + [dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey]; // Reset the text @@ -143,14 +145,12 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName names [dictionaryStack removeLastObject]; } -- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string -{ +- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { // Build the text value [textInProgress appendString:string]; } -- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError -{ +- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { // Set the error pointer to the parser's error object *errorPointer = parseError; }