2012-07-15 171 views
5

我试图从网站librarything.com解析XML文件(使用NSXMLParser)。这是我解析过的第一个文件,但大部分看起来相当简单。尝试解析CDATA块时发生问题;方法解析器:foundCDATA:没有被调用,我不明白为什么。我知道我的分析器设置正确,因为解析器:foundCharacters:方法工作正常。我试图解析的XML数据看起来像这样http://www.librarything.com/services/rest/1.1/?method=librarything.ck.getwork&isbn=030788743X&apikey=d231aa37c9b4f5d304a60a3d0ad1dad4,并且CDATA块出现在具有属性名称“description”的元素内。解析XML CDATA块

任何帮助,为什么该方法没有被称为将不胜感激!

编辑:我运行解析器:foundCharacters:在描述CDATA块上的方法,它返回“<”。我假设这意味着解析器没有正确地看到CDATA标签。有什么可以在我的最终解决这个问题?

回答

2

看起来<fact>标签中的CDATA内容正在通过parser:foundCharacters中的多个回调递增返回。在你的类,你都符合NSXMLParserDelegate尝试将其追加到的NSMutableString实例建立的CDATA,就像这样:

(注:此处_currentElement是一个NSString财产,_factString是的NSMutableString属性)

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {  
    self.currentElement = elementName; 
    if ([_currentElement isEqualToString:@"fact"]) { 
     // Make a new mutable string to store the fact string 
     self.factString = [NSMutableString string]; 
    } 

} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    if ([elementName isEqualToString:@"fact"]) { 
     // If fact string starts with CDATA tags then just get the CDATA without the tags 
     NSString *prefix = @"<![CDATA["; 
     if ([_factString hasPrefix:prefix]) { 
      NSString *cdataString = [_factString substringWithRange:NSMakeRange((prefix.length+1), _factString.length - 3 -(prefix.length+1))]; 
      // Do stuff with CDATA here... 
      NSLog(@"%@", cdataString); 
      // No longer need the fact string so make a new one ready for next XML CDATA 
      self.factString = [NSMutableString string]; 

     } 
    } 

} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if ([_currentElement isEqualToString:@"fact"]) { 
     // If we are at a fact element, append the string 
     // CDATA is returned to this method in more than one go, so build the string up over time 
     [_factString appendString:string]; 
    } 

}