2012-07-15 172 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]; 
    } 

}