2014-02-14 120 views
2

我在解析XML的問題,所以我通過我的代碼去與NSLogs,發現 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 不叫。的NSXMLParser「foundCharacters」委託方法

我的XML:

<?xml version="1.0"?> 
<locations> 
<location> 
<name>Americas</name> 
<address></address> 
<gid>CoQBdAAAAE2tdzw4RGvnvaUZTk6N1ByNtosmD--ZYfcmkkPkR6R6v_nN9gJCO1INOVg-S5rzy7BATEUmvAQzh8hClafZbph2wSgfD28gXNJAttXLUbqzQMaql3rVbisSUv2a2r_H6ktOSaI5lLvf0GNthT5jn2JfAdD_HfUls6qhMvrm5e5XEhDcF5uRjlfpSqI_aciS_QPaGhQVVHenbOKZBQMSoCzsoIsdfw313Q</gid> 
<type> 
<1>political</1><2/><3/><4/><5/> 
</type> 
<phone></phone> 
<rating></rating> 
<icon>http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png</icon> 
<website></website> 
<longitude>-105.2551187</longitude> 
<latitude>54.5259614</latitude> 
</location> 
</locations> 

我實現

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
... 
    if(!self.distance){self.distance = @"250000";} 
    NSString *string = [NSString stringWithFormat:@"http://fishbe.in/lab/reserverr/api/?term=%@&lat=%f&long=%f&limit=100&distance=%@", self.searchterm, location.coordinate.latitude, location.coordinate.longitude, self.distance]; 
    NSLog(@"%@", string); 
    NSURL *URL = [NSURL URLWithString:string]; 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL]; 

    [parser setDelegate:self]; 
    [parser setShouldResolveExternalEntities:NO]; 
    [parser setShouldProcessNamespaces:NO]; 
    [parser setShouldReportNamespacePrefixes:NO]; 
    [parser parse]; 
} 
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    self.element = elementName; 
    if ([self.element isEqualToString:@"locations"]) { 
     self.items = [[NSMutableArray alloc] init]; 
    } 

} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    NSLog(@"HI"); //Not outputted 
    if ([self.element isEqualToString:@"name"]) { 
     self.result = [[ReserverrSearchResult alloc] init]; 
     [self.result setTitle:string]; 
     NSLog(@"%@", string); 
    } else if ([self.element isEqualToString:@"address"]) { 
     [self.result setVicinity:string]; 
     NSLog(@"%@", string); 
    } else if ([self.element isEqualToString:@"gid"]) { 
     [self.result setGid:string]; 
     NSLog(@"%@", string); 
    } else if ([self.element isEqualToString:@"latitude"]) { 
     [self.result setLatitude:[string floatValue]]; 
     NSLog(@"%@", string); 
    } else if ([self.element isEqualToString:@"longitude"]) { 
     [self.result setLongitude:[string floatValue]]; 
     NSLog(@"%@", string); 
    } 

} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    if ([elementName isEqualToString:@"location"]) { 
     [self.items addObject:self.result]; 

    } 

} 

- (void)parserDidEndDocument:(NSXMLParser *)parser { 

    [self addAnnotations]; 

} 

編輯的相關部分 - 增加

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError 
{ 
    NSLog(@"%@",parseError); 
} 

,並沒有什麼。

+1

添加'parser:parseErrorOccurred:'並查看它是否說了什麼。 – Wain

回答

1

有幾個問題:

  1. 至於韋恩指出,應實現parser:parseErrorOccurred:,它會告訴你什麼是錯的。

  2. 如果searchterm包含URL的保留字符(例如空格,加號,和號等)的任何字符,我會期待問題。你應該總是百分號逃避什麼,我相信是一個用戶提供的搜索項,將其添加到URL:

    NSString *string = [NSString stringWithFormat:@"http://fishbe.in/lab/reserverr/api/?term=%@&lat=%f&long=%f&limit=100&distance=%@", [self percentEscapeString:self.searchterm], location.coordinate.latitude, location.coordinate.longitude, self.distance]; 
    

    在那裏你可以使用的方法如下所示:

    - (NSString *)percentEscapeString:(NSString *)string 
    { 
        NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
                           (CFStringRef)string, 
                           (CFStringRef)@" ", 
                           (CFStringRef)@":/[email protected]!$&'()*+,;=", 
                           kCFStringEncodingUTF8)); 
        return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"]; 
    } 
    

    注意,不要依靠stringByAddingPercentEscapesUsingEncoding做百分比轉義。你真的想要使用CFURLCreateStringByAddingPercentEscapes,就像上面一樣。

  3. 另一方面,您的XML格式不正確。我不相信NSXMLParser會接受數字的元素名稱。所以,與其:

    <type> 
        <1>political</1><2/><3/><4/><5/> 
    </type> 
    

    你可能想:

    <types> 
        <type>political</type> 
        <type></type> 
        <type></type> 
        <type></type> 
        <type></type> 
    </types> 
    

    或者,如果你真的需要那些數字標識符:

    <types> 
        <type id="1">political</type> 
        <type id="2"></type> 
        <type id="3"></type> 
        <type id="4"></type> 
        <type id="5"></type> 
    </types> 
    

    在後者的例子中,你didStartElement可以再使用attributeDict來提取id標識符。

  4. 您報告parseErrorOccurred沒有返回任何內容。這意味着你的服務器可能沒有任何回報。這可能是由許多問題造成的。嘗試使用您的URL並返回數據(例如,輸入NSStringNSData,而不是解析器)並查看響應的樣子。例如,用於測試目的,你可以這樣做:

    NSError *error; 
    NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error]; 
    NSString *results = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    
    // confirm error is `nil` and `results` is well-formed XML; 
    // you can then pass the `data` to `NSXMLParser` with `initWithData` if you want 
    

    我敢打賭那是空的(這對於某些搜索字詞可能因缺乏%的轉義原因引起,或從任何的服務器很多問題的)。

  5. 這可能不是一個問題,但值得注意的是,這是概念上的風險,以將結果保存到foundCharacters,因爲有時didStartElementdidEndElement之間,你必須多次調用foundCharacters檢索數據。通常人們會在didStartElement中實例化一個NSMutableString,將其附加到foundCharacters中,然後將其保存在didEndElement中。

+0

謝謝!除了現在我收到錯誤:'2014-02-14 13:16:41.949 Reserverr [940:70b] Error Domain = NSXMLParserErrorDomain Code = 68「操作無法完成。(NSXMLParserErrorDomain error 68.)在解析「gid」元素後,「UserInfo = 0x9d7d3a0 {NSXMLParserErrorLineNumber = 2,NSXMLParserErrorColumn = 323,NSXMLParserErrorMessage = StartTag:無效元素名稱 }' 。 – Phil

+1

@Phil是的,這是我的第三點,數字元素名稱是不允許的。這是不允許的'<1>'(等)。因此,我建議相應地更改XML。 – Rob