2014-02-14 2 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]; 

} 

Edit - Добавлена ​​

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

и не получили ничего.

+1

Добавить парсер: 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-адрес и верните данные (например, в NSString или NSData, а не в синтаксический анализатор) и посмотрите, как выглядел ответ. Например, для целей тестирования можно сделать:

    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, потому что иногда между didStartElement и didEndElement, вы будете иметь несколько вызовов foundCharacters для извлечения данных. Обычно люди будут создавать экземпляр NSMutableString в didStartElement, добавьте его в foundCharacters, а затем сохраните его в didEndElement.

+0

Спасибо! Это сработало, но теперь я получаю сообщение об ошибке: '2014-02-14 13: 16: 41.949 Reserverr [940: 70b] Ошибка домена = NSXMLParserErrorDomain Code = 68" Операция не может быть выполнена. (NSXMLParserErrorDomain ошибка 68.) «UserInfo = 0x9d7d3a0 {NSXMLParserErrorLineNumber = 2, NSXMLParserErrorColumn = 323, NSXMLParserErrorMessage = StartTag: недопустимое имя элемента }' после того, как он анализирует элемент «gid». – Phil

+1

@Phil Да, это мой третий пункт выше, что имена числовых элементов не разрешены. Это '<1>' (и т. Д.), Что недопустимо. Отсюда мое предложение изменить XML соответственно. – Rob