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

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

问题描述:

这是我的countries.xml文件。解析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文件,其中我的implemantig我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 
+0

你的问题是什么?如果你没有指明你的问题,我们该如何解决? – manujmv

+0

@manujmv我认为问题在那里的问题标题 –

+0

感谢您的帮助我git的问题... –

你的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); 

显然,如果你想学习如何u se 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


而且,如果你的数组和字典包含自定义对象,即比标准可可对象的其他NS对象(如NSStringNSNumberNSDate等),有一个名为NSKeyedArchiver另一种技术和NSKeyedUnarchiver,让你再次使用XML格式编写二进制plist文件,但是又一次避免了你自己写XML源的细节,也没有处理NSXMLParser。这更复杂一点,除非你使用自定义类来处理数组/字典,否则我不会担心它,但它是另一个很好的抽象,它可以处理XML文件,而无需处理XML本身。

+0

感谢@rob这帮了我很多 –

看来,在您的countries.xml文件中,您并未关闭countryn ame,但在一个国家的实际名称后再打开它。

+0

thabks但我的日志输出给我“” –

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

这会在解析器中导致错误,因此它会触发错误委托方法。

输出记录其中有无关的结果

+0

我怎么能得到数据? –