2014-02-12 2 views
1

Будучи сказанным, что я понимаю основной анализ XML-файлов с помощью NSXMLParser, у меня есть следующая ситуация, когда у меня есть несколько элементов <table_data>...</table_data>, которые отличаются друг от друга значением определенного атрибута, поэтому , например:NSXMLParser didStartElement только с определенным атрибутом

<table_data attr="one">...</table_data> 

<table_data attr="two">...</table_data> 

<table_data attr="three">...</table_data> 

в то время как в didStartElement, я хотел бы, что анализатор учитывает <table_data> элемента в качестве начального элемента, только если он имеет attr="one".

Это означало бы, что в foundCharacters я мог получить только содержание детей элементов <table_data attr="one"> но не <table_data attr="two">, <table_data attr="three"> и т.д.

К настоящему времени, я стараюсь это:

- (void)parser:(NSXMLParser*)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary*)attributeDict { 

    elementoCorrente = [elementName copy]; 

    if ([elementName isEqualToString:@"table_data"]) { 

     if ([[attributeDict objectForKey:@"attr"] isEqualToString:@"one"]) { 
      stringDesc = [[NSMutableString alloc] init]; 

     } 

    } 

} 


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 


    if ([elementoCorrente isEqualToString:@"field"]) { 

     [stringDesc appendString:string]; 
     NSLog(@"%@",string); 
    } 


} 

Но что Я получаю журнал содержимого элемента <field>, дочернего из всех <table_data>. Есть ли способ распечатать только содержимое элемента <field>, если дочерний элемент <table_data attr="one">? Благодаря Фабио

ответ

3

Проблема заключается в том, что вы ничего не делаете, чтобы остановить foundCharacters от добавления данных для других случаев table_data. Вы могли бы добавить didStartElement значение attributeDict[@"attr"], а затем foundCharacters может проверить как elementoCorrente так же как этот новый ivar, в котором вы держите attributeDict[@"attr"]. Например:

- (void)parser:(NSXMLParser*)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary*)attributeDict { 

    elementoCorrente = nil; 
    atributoCorrente = nil; 

    if ([elementName isEqualToString:@"table_data"]) { 

     if ([attributeDict[@"attr"] isEqualToString:@"one"]) { 
      elementoCorrente = [elementName copy]; 
      atributoCorrente = [attributeDict[@"attr"] copy]; 
      stringDesc = [[NSMutableString alloc] init]; 
     } 
    } 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if ([elementoCorrente isEqualToString:@"table_data"] && [atributoCorrente isEqualToString:@"one"]) { 

     [stringDesc appendString:string]; 
    } 
} 

Честно говоря, вы, вероятно, хотите didEndElement реализации, тоже, что экономит stringDesc где бы вы хотели, чтобы сохранить его, а затем устанавливает elementoCorrente в nil.

+0

Это, на мой взгляд, правильный ответ. И невероятно, насколько это было легко. Позор мне ... Большое спасибо Робу, который потратил время, чтобы предоставить мне рабочий код тоже :) Кроме того, ответ Хелдердароча - работающий и хороший, благодаря вам обоим, я могу продолжить! –

1

Возможно, фрагмент кода что-то не хватает, но от того, что вы показываете здесь, чтобы распечатать содержимое всех field тегов является ожидаемое поведение, так как только тест вы делаете в метод parser:foundCharacters:, если текущий элемент равен field.

Вы можете добавить флаг, указывающий, что вы находитесь внутри table_data с attr_one. Что-то вроде:

if ([[attributeDict objectForKey:@"attr"] isEqualToString:@"one"]) { 
    stringDesc = [[NSMutableString alloc] init]; 
    insideTableOne = YES; 
} 

А потом, в parser:foundCharacters: также проверить, если insideTableOne верно перед добавлением строки.

Этот тест также необходим, чтобы ваша программа не сработала, если она найдет table_data без ожидаемого атрибута. Если это произойдет, то stringDesc еще не был создан.

Смежные вопросы