解析XML时出错“解析文档时出错!”

时间:2013-05-27 11:53:30

标签: ios nsxmlparser

这是我的countries.xml文件。

有什么问题请回答我,我是iOS的新手.....

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<countris>
<country>
    <countryname>india<countryname>    
</country>
</countris>
</plist>

这是我的viewDidLoad

NSString *filename = [[NSBundle mainBundle] pathForResource:@"countris" ofType:@"xml"];
NSData *data = [NSData dataWithContentsOfFile:filename];


NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

Myparser *myParser = [[Myparser alloc] init];

[parser setDelegate:myParser];

BOOL success = [parser parse];

if (success)
{
    NSMutableArray *users = [myParser arraydata];
    NSString *log= [NSString stringWithFormat:
                          @"This is an array of User objects:\n\n%@",
                          [users description]];
    NSLog(log);
}
else
{
    NSLog(@"Error parsing document!");

    [[[UIAlertView alloc] initWithTitle:nil
                                message:@"Error parsing document!"
                               delegate:nil
                      cancelButtonTitle:@"OK"
                      otherButtonTitles:nil] show];
}

我的Myparser.m文件,其中我是一个实现我的NSXMLParserDelegate协议

#import "Myparser.h"
#import "MyParserData.h"

@implementation Myparser

@synthesize mydata,myparser,arraydata,flag,currentElementValue;

- (id) init {

    if(self = [super init]) {
        currentElementValue = [[NSMutableString alloc] initWithString:@""];
        arraydata = [[NSMutableArray alloc] init];
        flag = FALSE;
    }
    return self;
}

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict {

    if ([elementName isEqualToString:@"countris"]) {
        return;
    } else if ([elementName isEqualToString:@"country"]) {
        self.mydata  = [[MyParserData alloc] init];
         } else {
        self.currentElementValue = [[NSMutableString alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (self.currentElementValue) {
        [self.currentElementValue appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parserdidEndElement:(NSString *)elementNamenamespaceURI:          (NSString *)namespaceURIqualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"counteis"]) {

        return;
    }

    if ([elementName isEqualToString:@"country"]) {
        [self.arraydata addObject:mydata];
        self.mydata = nil;
    } else {
        [self.mydata setValue:self.currentElementValue forKey:elementName];
    }

    self.currentElementValue = nil;
}

@end

3 个答案:

答案 0 :(得分:2)

WRONG    <countryname>india<countryname>    
RIGHT    <countryname>india</countryname>    

这会导致解析器出错,因此会遇到错误委托方法。

输出记录解析器的内存,该内存与结果

无关

答案 1 :(得分:1)

似乎在您的countries.xml文件中,您没有关闭countryname,而是在国家/地区的实际名称后再次打开它。

答案 2 :(得分:1)

您的XML无效。您有一个<countryname>代码,但是您永远不会将其关闭(即您错过了/中的</countryname>)。

使用NSXMLParser时,我建议您实施parseErrorOccurred,然后查看错误对象,它通常会为您提供有关在XML源中查找问题的位置的见解。 Cocoa框架通常非常适合提供获取错误信息的方法,因此可以利用这些技术。


顺便说一句,我注意到你似乎试图使用plist格式,但它并不完全符合正确的格式,就像你手工编写XML一样。通常,如果您使用plist文件,则根本不需要使用NSXMLParser(也不会手动创建XML源)。

想象一下以下源代码:

NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filename = [docsPath stringByAppendingPathComponent:@"test.plist"];

NSDictionary *dictionary = @{@"countries": @{@"country" : @"india"}};
[dictionary writeToFile:filename atomically:YES];

这会创建一个test.plist文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>countries</key>
    <dict>
        <key>country</key>
        <string>india</string>
    </dict>
</dict>
</plist>

问题是,一旦使用writeToFile创建一个plist,您现在可以将其读作:

dictionary = [NSDictionary dictionaryWithContentsOfFile:filename];
NSLog(@"dictionary = %@", dictionary);

显然,如果您正在尝试学习如何使用NSXMLParser,请继续进行实验。但是,在使用plist文件时,您只需使用writeToFile保存并加载dictionaryWithContentsOfFile即可简化流程。

顺便说一句,此过程不仅适用于NSDictionary个对象,也适用于NSArray个对象。例如,考虑这个字典数组:

// create array plist

filename = [docsPath stringByAppendingPathComponent:@"array.plist"];
NSArray *array = @[@{@"country" : @"india"}, @{@"country" : @"france"}];
[array writeToFile:filename atomically:YES];

// read array plist

array = [NSArray arrayWithContentsOfFile:filename];

但是这个想法是你可以用XML格式保存字典和数组,而不必自己接触XML源,也不必处理NSXMLParser

有关详细信息,请参阅Property List Programming Guide


并且,如果您的数组和字典包含自定义对象,即标准Cocoa NS对象以外的对象(例如NSStringNSNumberNSDate等。 ),还有另一种称为NSKeyedArchiverNSKeyedUnarchiver的技术,它允许您再次使用XML格式编写二进制plist文件,但是再一次让您免于自己编写XML源代码的细节,也没有处理NSXMLParser。它有点复杂,我不担心它,除非你用自定义类处理数组/字典,但它是另一个很好的抽象,它可以处理XML文件而无需处理XML本身。