2010-11-17 4 views
3

эй, ребята, у меня вопрос с разбором xml. Как правило, стиль файла XML, как это:Парсер XML с NSXMLParser

<person> 
    <name> abc </name> 
    <age> 19 </age> 
    <gender> male </gender> 
</person> 

Таким образом, мы используем

elementName isEqualToString:@"name" 
elementName isEqualToString:@"age" 
elementName isEqualToString:@"gender" 

для идентификации элемента.

Теперь я столкнулся стиль файла XML, как:

<person> 
    <element type="name">abc</element> 
    <element type="age">19</element> 
    <element type="gender">male</element> 
</person> 

В этой ситуации, мы не можем использовать

elementName isEqualToString:@"name" 

Так что я пытался использовать

if ([elementName isEqualToString:@"element"]) { 
    if ([[attributeDict objectForKey:@"type"] isEqualToString:@"name"){ 
     ..... 
    } 
} 

, чтобы определить «имя», но это не дало мне никакого значения, нет ничего, если бы я попытался получить значение «имя».

Итак, есть ли у кого-нибудь предложения по устранению этой проблемы? благодаря

PS: Вот часть моего кода

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


    if ([elementName isEqualToString:@"area"]) { 
     if ([[attributeDict objectForKey:@"type"] isEqualToString:@"location"]) { 
      NSString *description = [attributeDict objectForKey:@"description"]; 

      NSArray *lineEntry = [[NSArray alloc] initWithObjects:description,nil ]; 
      NSArray *lineKeys = [[NSArray alloc] initWithObjects:@"description",nil]; 
      NSDictionary *dictItem = [[NSDictionary alloc] initWithObjects:lineEntry forKeys:lineKeys]; 

      [lineKeys release]; 
      [lineEntry release]; 

      [dataLoad addObject:dictItem]; 
      [dictItem release]; 
     } 

    } 

    if ([elementName isEqualToString:@"forecast-period"]) { 

     NSString *index = [attributeDict objectForKey:@"index"]; 
     NSString *time = [attributeDict objectForKey:@"start-time-local"]; 


     NSArray *indexEntry = [[NSArray alloc] initWithObjects:index,time,nil]; 
     NSArray *indexKey = [[NSArray alloc] initWithObjects:@"index",@"start-time-local",nil]; 

     NSDictionary *dicIndex = [[NSDictionary alloc] initWithObjects:indexEntry forKeys:indexKey]; 

     [indexEntry release]; 
     [indexKey release]; 

     [weatherLoad addObject:dicIndex]; 
     [dicIndex release]; 


    } 
} 

он работал отлично с этими 2-х частей, но это не работает, если я пытаюсь получить «forecast_icon_code», «air_temperature_minimum», «air_temperature_maximum» «конспект».

<forecast-period index="1" start-time-local="2010-11-19T00:00:00+11:00" end-time-local="2010-11-20T00:00:00+11:00" start-time-utc="2010-11-18T13:00:00Z" end-time-utc="2010-11-19T13:00:00Z"> 
<element type="forecast_icon_code">1</element> 
<element type="air_temperature_minimum" units="Celsius">12</element> 
<element type="air_temperature_maximum" units="Celsius">24</element> 
<text type="precis">Sunny.</text> 
</forecast-period> 

Любые предложения? BTW, весь xml-файл находится здесь: ftp://ftp2.bom.gov.au/anon/gen/fwo/IDV10753.xml

+0

Вы уверены, что вы используете NSXMLParser? Это SAX-парсер, то есть вы получать обратный вызов каждый раз, когда он попадает в начало/конец элемента и т. д. - API не запрашивает элемент по имени. NSXML больше похож на то, о чем вы говорите. –

+1

Небольшая часть кода, который вы используете отправленный весь код из всех методов делегирования NSXMLParser, которые вы реализуете. – Anna

+0

Да, я использую NSXMLParser. Исходный XML не так прост, им просто путают в этом виде XML style. Нет проблем, если XML-файл не имеет . – david

ответ

2

Я предполагаю, что вы хотите, чтобы все «элементы» прогнозный период будут добавлены в тот же словарь вы кладете индекс и старт-время локального?

Исходное базовое if-заявление, опубликованное в вопросе, прекрасно, но проблема в том, что с помощью NSXMLParser каждый тег xml («период прогноза», «элемент», «текст» и т. Д.) Вызывает метод didStartElement Огонь.

Поскольку существует несколько тегов «прогнозируемого периода» и несколько тегов «элемента», ваш код должен будет отслеживать, каков текущий родительский тег/объект. После обработки тега «прогнозируемый период» didStartElement снова запускается для следующего тега «element». В этом вызове параметры метода не будут указывать на то, что этот «элемент» является дочерним элементом «прогноза-периода» с «индексом» 1. Ваш код должен отслеживать это.

Кроме того, поскольку теги «element» имеют действительные значения (например, «Sunny» для типа = precis), вам придется реализовать найденные символы и didEndElement.

В didEndElement, на основе текущего целевого объекта, вы должны поместить данные в нужное место. Если это конец «прогноза-периода», ничего не делайте (он не имеет значения). Если это конец тега «element», вы должны взять значение, захваченное foundCharacters, и добавить его в последний словарь в weatherLoad. Это также означает, что вам нужно перейти на использование NSMutableDictionary вместо NSDictionary.

Ссылка, которую @itsaboutcode дал вам есть хороший пример всего выше (это выше в разделе «Обработка Атрибуты».

+0

спасибо i'v получил его – david

0

Чтение раздела в разделе «Обработка атрибутов» в Apple Event Driven XML Programming, и у вас будет ваш ответ.

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/XMLParsing/Articles/HandlingElements.html#//apple_ref/doc/uid/20002265-1001969

+0

. Это делает работу с этой ситуацией. – david

+0

@David - как предположил aBitObvious, это путь, но у вас могут быть проблемы в какой-то другой части. – itsaboutcode

+0

обновленная часть моей коды в вопросе – david

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