0

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

我有大约 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文件或字典等,通过它也可以实现代码优化。

4

2 回答 2

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 文件的值。

最后在应用启动过程中做必要的解析,在does finish启动方法中,即:

- (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]];
         }
      }
   }
}

希望这对某人有所帮助,谢谢,编码愉快:)

于 2013-06-18T07:37:55.910 回答
-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];
于 2013-06-06T08:18:34.550 回答