mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-29 05:05:34 +08:00
This commit is contained in:
20
Vendor/XMLReader/XMLReader.h
vendored
Executable file → Normal file
20
Vendor/XMLReader/XMLReader.h
vendored
Executable file → Normal file
@@ -1,25 +1,29 @@
|
||||
//
|
||||
// XMLReader.h
|
||||
//
|
||||
// Created by Troy on 9/18/10.
|
||||
// Updated by Antoine Marcadet on 9/23/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
enum {
|
||||
XMLReaderOptionsProcessNamespaces = 1 << 0, // Specifies whether the receiver reports the namespace and the qualified name of an element.
|
||||
XMLReaderOptionsReportNamespacePrefixes = 1 << 1, // Specifies whether the receiver reports the scope of namespace declarations.
|
||||
XMLReaderOptionsResolveExternalEntities = 1 << 2, // Specifies whether the receiver reports declarations of external entities.
|
||||
};
|
||||
typedef NSUInteger XMLReaderOptions;
|
||||
|
||||
@interface XMLReader : NSObject <NSXMLParserDelegate>
|
||||
{
|
||||
NSMutableArray *dictionaryStack;
|
||||
NSMutableString *textInProgress;
|
||||
NSError **errorPointer;
|
||||
NSError * __autoreleasing *errorPointer;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer;
|
||||
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
|
||||
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;
|
||||
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(XMLReaderOptions)options error:(NSError **)errorPointer;
|
||||
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(XMLReaderOptions)options error:(NSError **)errorPointer;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSDictionary (XMLReaderNavigation)
|
||||
|
||||
- (id)retrieveForPath:(NSString *)navPath;
|
||||
|
||||
@end
|
||||
160
Vendor/XMLReader/XMLReader.m
vendored
160
Vendor/XMLReader/XMLReader.m
vendored
@@ -1,109 +1,65 @@
|
||||
//
|
||||
// XMLReader.m
|
||||
//
|
||||
// Created by Troy on 9/18/10.
|
||||
// Updated by Antoine Marcadet on 9/23/11.
|
||||
//
|
||||
|
||||
#import "XMLReader.h"
|
||||
|
||||
NSString *const kXMLReaderTextNodeKey = @"text";
|
||||
NSString *const kXMLReaderAttributePrefix = @"";
|
||||
NSString *const kXMLReaderTextNodeKey = @"text";
|
||||
NSString *const kXMLReaderAttributePrefix = @"@";
|
||||
|
||||
@interface XMLReader (Internal)
|
||||
@interface XMLReader ()
|
||||
|
||||
- (id)initWithError:(NSError **)error;
|
||||
- (NSDictionary *)objectWithData:(NSData *)data;
|
||||
- (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSDictionary (XMLReaderNavigation)
|
||||
|
||||
- (id)retrieveForPath:(NSString *)navPath
|
||||
{
|
||||
// Split path on dots
|
||||
NSArray *pathItems = [navPath componentsSeparatedByString:@"."];
|
||||
|
||||
// Enumerate through array
|
||||
NSEnumerator *e = [pathItems objectEnumerator];
|
||||
NSString *path;
|
||||
|
||||
// Set first branch from self
|
||||
id branch = [self objectForKey:[e nextObject]];
|
||||
int count = 1;
|
||||
|
||||
while ((path = [e nextObject]))
|
||||
{
|
||||
// Check if this branch is an NSArray
|
||||
if([branch isKindOfClass:[NSArray class]])
|
||||
{
|
||||
if ([path isEqualToString:@"last"])
|
||||
{
|
||||
branch = [branch lastObject];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([branch count] > [path intValue])
|
||||
{
|
||||
branch = [branch objectAtIndex:[path intValue]];
|
||||
}
|
||||
else
|
||||
{
|
||||
branch = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// branch is assumed to be an NSDictionary
|
||||
branch = [branch objectForKey:path];
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return branch;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation XMLReader
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Public methods
|
||||
|
||||
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer
|
||||
{
|
||||
NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"xml"];
|
||||
NSData *data = [[NSFileManager defaultManager] contentsAtPath:fullpath];
|
||||
NSDictionary *rootDictionary = [XMLReader dictionaryForXMLData:data error:errorPointer];
|
||||
|
||||
return rootDictionary;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
|
||||
{
|
||||
XMLReader *reader = [[XMLReader alloc] initWithError:error];
|
||||
NSDictionary *rootDictionary = [reader objectWithData:data];
|
||||
NSDictionary *rootDictionary = [reader objectWithData:data options:0];
|
||||
[reader release];
|
||||
|
||||
return rootDictionary;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
|
||||
{
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
return [XMLReader dictionaryForXMLData:data error:error];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(XMLReaderOptions)options error:(NSError **)error
|
||||
{
|
||||
XMLReader *reader = [[XMLReader alloc] initWithError:error];
|
||||
NSDictionary *rootDictionary = [reader objectWithData:data options:options];
|
||||
[reader release];
|
||||
return rootDictionary;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(XMLReaderOptions)options error:(NSError **)error
|
||||
{
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return [XMLReader dictionaryForXMLData:data options:options error:error];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Parsing
|
||||
|
||||
- (id)initWithError:(NSError **)error
|
||||
{
|
||||
if ((self = [super init]))
|
||||
if (self = [super init])
|
||||
{
|
||||
errorPointer = error;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -111,11 +67,10 @@ NSString *const kXMLReaderAttributePrefix = @"";
|
||||
{
|
||||
[dictionaryStack release];
|
||||
[textInProgress release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSDictionary *)objectWithData:(NSData *)data
|
||||
- (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options
|
||||
{
|
||||
// Clear out any old data
|
||||
[dictionaryStack release];
|
||||
@@ -129,45 +84,44 @@ NSString *const kXMLReaderAttributePrefix = @"";
|
||||
|
||||
// Parse the XML
|
||||
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
|
||||
|
||||
[parser setShouldProcessNamespaces:(options & XMLReaderOptionsProcessNamespaces)];
|
||||
[parser setShouldReportNamespacePrefixes:(options & XMLReaderOptionsReportNamespacePrefixes)];
|
||||
[parser setShouldResolveExternalEntities:(options & XMLReaderOptionsResolveExternalEntities)];
|
||||
|
||||
parser.delegate = self;
|
||||
BOOL success = [parser parse];
|
||||
|
||||
[parser release];
|
||||
|
||||
// Return the stack's root dictionary on success
|
||||
if (success)
|
||||
{
|
||||
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
|
||||
|
||||
return resultDict;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSXMLParserDelegate methods
|
||||
|
||||
- (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];
|
||||
|
||||
// Create the child dictionary for the new element
|
||||
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
|
||||
|
||||
// Initialize child dictionary with the attributes, prefixed with '@'
|
||||
for (NSString *key in attributeDict) {
|
||||
[childDict setValue:[attributeDict objectForKey:key]
|
||||
forKey:[NSString stringWithFormat:@"%@%@", kXMLReaderAttributePrefix, key]];
|
||||
}
|
||||
// Create the child dictionary for the new element, and initilaize it with the attributes
|
||||
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
|
||||
[childDict addEntriesFromDictionary:attributeDict];
|
||||
|
||||
// If there's already an item for this key, it means we need to create an array
|
||||
id existingValue = [parentDict objectForKey:elementName];
|
||||
|
||||
if (existingValue)
|
||||
{
|
||||
NSMutableArray *array = nil;
|
||||
|
||||
if ([existingValue isKindOfClass:[NSMutableArray class]])
|
||||
{
|
||||
// The array exists, so use it
|
||||
@@ -178,7 +132,7 @@ NSString *const kXMLReaderAttributePrefix = @"";
|
||||
// Create an array if it doesn't exist
|
||||
array = [NSMutableArray array];
|
||||
[array addObject:existingValue];
|
||||
|
||||
|
||||
// Replace the child dictionary with an array of children dictionaries
|
||||
[parentDict setObject:array forKey:elementName];
|
||||
}
|
||||
@@ -201,54 +155,32 @@ NSString *const kXMLReaderAttributePrefix = @"";
|
||||
// Update the parent dict with text info
|
||||
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
|
||||
|
||||
// Pop the current dict
|
||||
[dictionaryStack removeLastObject];
|
||||
|
||||
// Set the text property
|
||||
if ([textInProgress length] > 0)
|
||||
{
|
||||
if ([dictInProgress count] > 0)
|
||||
{
|
||||
[dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Given that there will only ever be a single value in this dictionary, let's replace the dictionary with a simple string.
|
||||
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
|
||||
id parentObject = [parentDict objectForKey:elementName];
|
||||
|
||||
// Parent is an Array
|
||||
if ([parentObject isKindOfClass:[NSArray class]])
|
||||
{
|
||||
[parentObject removeLastObject];
|
||||
[parentObject addObject:textInProgress];
|
||||
}
|
||||
|
||||
// Parent is a Dictionary
|
||||
else
|
||||
{
|
||||
[parentDict removeObjectForKey:elementName];
|
||||
[parentDict setObject:textInProgress forKey:elementName];
|
||||
}
|
||||
}
|
||||
|
||||
// trim after concatenating
|
||||
NSString *trimmedString = [textInProgress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
[dictInProgress setObject:[[trimmedString mutableCopy] autorelease] forKey:kXMLReaderTextNodeKey];
|
||||
|
||||
// Reset the text
|
||||
[textInProgress release];
|
||||
textInProgress = [[NSMutableString alloc] init];
|
||||
}
|
||||
|
||||
// Pop the current dict
|
||||
[dictionaryStack removeLastObject];
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
|
||||
{
|
||||
// Build the text value
|
||||
[textInProgress appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
|
||||
[textInProgress appendString:string];
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
|
||||
{
|
||||
// Set the error pointer to the parser's error object
|
||||
if (errorPointer)
|
||||
*errorPointer = parseError;
|
||||
*errorPointer = parseError;
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user