从xml文件中获取数据的有效且简单的方法

时间:2013-06-06 07:57:32

标签: ios iphone xml cocoa-touch fetch

我知道有几种方法可以使用NSXMLParser,RaptureXML,TouchXML等解析xml文件的数据,但是当我使用NSXMLParser方法时,它似乎是一个漫长的过程,因为我们必须声明字符串,数组等。我有一个xml文件,大约有7个类别,也有3个级别,我的xml文件是以下format,它被复制到我项目的支持文件文件夹。我恳请请一瞥它以便理解。

我有大约21个标签,我需要从每个类别中获取数据,这意味着我需要声明大约21个数组,单独的字符串等,如果有的话我没有错!

我试图从一个类别(动物一级)获取数据。但是我没有观察到数组中的数据,我不知道如何从这里开始:

-(void)parseAndFetchWords
{
    self.animalsWordsArray = [NSMutableArray array];
    NSString *xmlFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"strings" ofType:@"xml"];
    NSURL *xmlLocationURL = [NSURL URLWithString:xmlFilePath];
    self.parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlLocationURL];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}
#pragma mark - Parser Delegate
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    currentElement = nil;
    currentElement = [elementName copy];
    if ([elementName isEqualToString:@"animalLevelOne"])
    {
        self.animalName = [NSMutableString string];
        self.animalHint = [NSMutableString string];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet controlCharacterSet]];

    if ([currentElement isEqualToString:@"animalLevelOne"])
    {
        [animalName appendString:string];
    }
    else if ([currentElement isEqualToString:@"animalLevelOne"])
    {
        [animalHint appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"animalLevelOne"])
    {
        NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        [dictionary setObject:animalName forKey:@"animalName"];
        [dictionary setObject:animalHint forKey:@"animalHint"];
        //And finally
        [self.animalsWordsArray addObject:dictionary];
    }
}

有人可以建议一种更好,更简单的方法从xml获取数据,可能没有解析,比如将xml转换为plist文件或字典等,通过它们也可以实现代码优化。

2 个答案:

答案 0 :(得分:1)

我找到了一个很酷的解决方案,解决了如何解析xml文件而没有任何麻烦。

获取一个模型类,并将其命名为带有头文件和主文件的XMLParser,在模型类中声明所有必需的变量和方法,比如说我的情况是:

@property(strong,nonatomic) NSMutableString *currentElementValue;
@property(strong,nonatomic) wordJumblesAppDelegate *appDelegate;
@property(strong,nonatomic) NSMutableArray *objects;

//Method for parsing....
-(XMLParser *)initXMLParser;

请理解currentElementValue是整个xml文件的每个标记中的值,并且声明appDelegate对象将所有已解析的数据存储在委托类中声明的字典中。对象只是一个用于存储每个标记的所有值的数组

现在让我们继续讨论实施部分

-(XMLParser *)initXMLParser
{
    self = [super init];
    self.appDelegate = (gameAppDelegate *)[[UIApplication sharedApplication]delegate];
    return self;
}

实现解析器委托方法:

//Start parsing the xml file using did start element
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDictionary
{
    if([elementName isEqualToString:@"resources"])
    {
        appDelegate.categoryWords = [NSMutableDictionary dictionary];
    }
    else if([elementName isEqualToString:@"string-array"])
    {
        self.objects = [NSMutableArray array];
        if (objects)
        {
            [appDelegate.categoryWords setObject:objects forKey:[attributeDictionary objectForKey:@"name"]];
        }
    }
}

//Search for characters in each tag and assign the value to our currentElementValue
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if(!currentElementValue)
    {
        self.currentElementValue = [[NSMutableString alloc] initWithString:string];
    }
    else
    {
        [currentElementValue appendString:string];
    }
}

//Finally add the currentElementValue to our objects array
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"resources"])
        return;
    if([elementName isEqualToString:@"string-array"])
    {
    }
    else
    {
        [objects  addObject:currentElementValue];
    }
    self.currentElementValue = nil;
}

请注意我们将对象数组存储在应用程序委托文件中声明的类别单词字典中,以便我们可以使用字典访问项目中所需的xml文件的所有值。

最后在应用程序启动期间进行必要的解析,完成启动方法,即:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
    NSString *xmlFilePath = [[NSBundle mainBundle]pathForResource:@"categoryWords" ofType:@"xml"];
    NSURL *url = [NSURL fileURLWithPath:xmlFilePath];

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

    //Initialize the delegate.
    XMLParser *parser = [[XMLParser alloc] initXMLParser];

    //Set delegate
    [xmlParser setDelegate:(id)parser];

    //Start parsing the XML file.
    BOOL success = [xmlParser parse];

    if(success)
);
    else
        NSLog(@"Error Error Error!!!");
return YES;
}

示例代码,用于从categoryWords字典中检索数据

NSArray *allCategories = [applicationDelegate.categoryWords allKeys];
for (NSString *category in allCategories)
{
   if ([category isEqualToString:@"animalLevelOne"])
   {
      NSArray *animalsEasyData = [NSArray arrayWithObject:[applicationDelegate.categoryWords objectForKey:category]];
      for (NSArray *animalsEasy in animalsEasyData)
      {
         for (NSString *animal in animalsEasy)
         {
            NSArray *trimmedAnimalsEasyData = [animal componentsSeparatedByString:@"@"];
            [self.animalsEasyWords addObject:[trimmedAnimalsEasyData objectAtIndex:0]];
            [self.animalsEasyHints addObject:[trimmedAnimalsEasyData objectAtIndex:1]];
         }
      }
   }
}

希望这有助于某人,谢谢,快乐的编码:)

答案 1 :(得分:-1)

请尝试使用此代码在.plist

中存储字典
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *docFilePath = [documentsDirstringByAppendingPathComponent:@"UserSettings.plist"];

NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:0];

// add the data to dict here
[dict setObject:allMsgs forKey:@"allMsgsKey"];

// save the data as plist`enter code here`
[dict writeToFile:docFilePath atomically:YES];
[dict release];