/* * parseUtils.m * Geopher iPad * * Created by Jeremy on 11/29/10. * Copyright 2010 Stone Software. All rights reserved. * */ #include "ParseUtils.h" #import "TouchXML.h" #import "SavedCachesController.h" #import "XMLReader.h" #pragma mark - NSArray* parseGPXFileToDict_OpenCachingFormat(NSString* path) { NSArray* retVal = nil; NSError* err = nil; NSData* data = [NSData dataWithContentsOfFile:path]; if (data) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSDictionary* dict = [XMLReader dictionaryForXMLData:data error:&err]; if (!err) { [dict writeToFile:[documentsDirectory stringByAppendingPathComponent:@"aaaTextFile.txt"] atomically:YES]; id root = [dict objectForKey:@"gpx"]; id obj = [root objectForKey:kGPXWaypoint]; if (obj) { if ([obj isKindOfClass:[NSArray class]]) retVal = obj; // return the array else if ([obj isKindOfClass:[NSDictionary class]]) retVal = [NSArray arrayWithObject:obj]; // return as an array of one } } else { NSLog(@"Error parsing XML file, error %hi, %@", [err code], [err localizedDescription]); } } if (!retVal) retVal = [NSArray array]; // always return something, may just be an empty array. return retVal; } // This will parse all geocaches out of a GPX file and return them in an array. // NSArray* parseGPXFileToDict(NSString* inFilePath) { NSArray* retVal = nil; NSMutableArray* ourArray = [NSMutableArray array]; retVal = parseGPXFileToDict_OpenCachingFormat(inFilePath); // NSString* str = nil; // if (inFilePath) // { // NSError* err = nil; // NSStringEncoding encoding = 0; // str = [NSString stringWithContentsOfFile:inFilePath usedEncoding:&encoding error:&err]; // } // // // now parse the string // if (str) // { // NSError* err = nil; // CXMLDocument* doc = [[CXMLDocument alloc] initWithXMLString:str options:CXMLDocumentTidyXML error:&err]; // CXMLElement* root = [doc rootElement]; // NSArray* authorList = [root elementsForName:kGPXAuthor]; // if (authorList && [authorList count]) // { // NSString* author = [authorList objectAtIndex:0]; // if ([author rangeOfString:@"OpenCaching"].location != NSNotFound) // retVal = parseGPXFileToDict_OpenCachingFormat(inFilePath); // } // else // { // // assume openCaching format if we aren't sure. // retVal = parseGPXFileToDict_OpenCachingFormat(inFilePath); // } // // [doc release]; // } if ([ourArray count]) retVal = ourArray; return retVal; } #pragma mark - // This will parse all "waypoint" types out of a LOC file and return them in an array. // NSArray* parseLocFileToDict(NSString* inFilePath) { NSArray* retVal = nil; NSMutableArray* ourArray = [NSMutableArray array]; NSString* str = nil; if (inFilePath) { NSError* err = nil; NSStringEncoding encoding = 0; str = [NSString stringWithContentsOfFile:inFilePath usedEncoding:&encoding error:&err]; } // now parse the string if (str) { NSError* err = nil; CXMLDocument* doc = [[CXMLDocument alloc] initWithXMLString:str options:CXMLDocumentTidyXML error:&err]; CXMLElement* root = [doc rootElement]; NSArray* waypoints = [root elementsForName:kLOCWaypointName]; for (CXMLNode* node in waypoints) { // each iteration is a single waypoint entry in our list. NSMutableDictionary* dict = [NSMutableDictionary dictionary]; NSArray* info = [node children]; for (CXMLNode* data in info) { BOOL add = YES; // set to no to skip if ([data kind] == CXMLElementKind) { CXMLElement* ele = (CXMLElement*)data; // pull out any attributes we may want into our dict as we go. NSArray* attribs = [ele attributes]; for (CXMLNode* nd in attribs) { if ([nd.name isEqualToString:kLOCLatitudeNodeName]) [dict setObject:[nd stringValue] forKey:kLOCLatitudeNodeName]; else if ([nd.name isEqualToString:kLOCLongitudeNodeName]) [dict setObject:[nd stringValue] forKey:kLOCLongitudeNodeName]; else if ([nd.name isEqualToString:kLOCCacheGeocode]) [dict setObject:[nd stringValue] forKey:kLOCCacheGeocode]; else add = NO; } } if ([[data stringValue] length] == 0) add = NO; else if ([data kind] == CXMLTextKind) add = NO; if (add) [dict setObject:[data stringValue] forKey:[data name]]; } if ([dict count] > 0) [ourArray addObject:dict]; } [doc release]; } if ([ourArray count]) retVal = ourArray; return retVal; }