2012-04-01 8 views
0

Ich habe eine Datei xml wie folgt aus:IOS: NSMXLParser mit mehreren Knoten

<data> 
    <first> 
     <city> 
      city 
     </city> 
     <people> 
      400 
     </people> 
    </first> 
    <size> 
     <width> 
      340 
     </width> 
     <height> 
      120 
     </height> 
    </size> 
    <description> 
     <temp> 
      sunny 
     </temp> 
     <people> 
      45 
     </people> 
    </description> 
    <description> 
     <temp> 
      cloudy 
     </temp> 
     <people> 
       90 
     </people> 
    </description> 

ich für das Parsen von diesen Code verwenden:

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

    currentElement = [elementName copy]; 
    if ([elementName isEqualToString:@"first"]) { 
     firstType = [[NSMutableDictionary alloc] init]; 
     currentCity = [[NSMutableString alloc] init]; 
     currentPeople = [[NSMutableString alloc] init]; 
    } 

    if ([elementName isEqualToString:@"size"]){ 
     currentSize = [[NSMutableDictionary alloc] init]; 
     width = [[NSMutableString alloc]init]; 
     height = [[NSMutableString alloc]init]; 
    } 

    if ([elementName isEqualToString:@"description"]){ 
     desc1 = [[NSMutableDictionary alloc] init]; 
     temp1 = [[NSMutableString alloc]init]; 
     people1 = [[NSMutableString alloc]init]; 
    } 

    if ([elementName isEqualToString:@"description"]){ 
     desc2 = [[NSMutableDictionary alloc] init]; 
     temp2 = [[NSMutableString alloc]init]; 
     people2 = [[NSMutableString alloc]init]; 
    } 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{  

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

     [firstType setObject:currentType forKey:@"city"]; 
     [firstType setObject:currentQuery forKey:@"people"]; 
       [feed addObject:[firstType copy]]; 
    } 
    if ([elementName isEqualToString:@"size"]){ 

     [currentSize setObject:tempC forKey:@"width"]; 
     [currentSize setObject:tempF forKey:@"height"]; 
     [feed addObject:[currentSize copy]]; 
    } 
    if ([elementName isEqualToString:@"description"]){ 

     [desc1 setObject:temp1 forKey:@"temp1"]; 
     [desc1 setObject:people1 forKey:@"people1"]; 
     [feed addObject:[desc1 copy]]; 
    } 

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

     [desc2 setObject:temp1 forKey:@"temp2"]; 
     [desc2 setObject:people1 forKey:@"people2"]; 
     [feed addObject:[desc2 copy]]; 
    } 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 
    NSLog(@"found"); 
    if ([currentElement isEqualToString:@"city"]){ 
     [currentCity appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"people"]) { 
     [currentPeople appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"width"]){ 
     [width appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"height"]){ 
     [height appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"temp"]){ 
     [temp1 appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"temp"]){ 
     [temp2 appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"people"]){ 
     [people1 appendString:string]; 
    } 
    else if ([currentElement isEqualToString:@"people"]){ 
     [people2 appendString:string]; 
    } 

} 

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

    NSLog(@"feed:%@",feed); 
} 

das Ergebnis NSLog ist:

feed:(
     { 
     city = city; 
     people = 4004590; 
    }, 
     { 
     width = 340; 
     height = 120; 
    }, 
     { 
     temp = sunny; 
     people = ""; 
    }, 
     { ///???? here there is an empty space 
    }, 
     { 
     temp = cloudy; 
     people = ""; 
    }, 
     { 
    } 
) 

Jetzt verstehe ich nicht, warum es einen Abstand zwischen dem ersten Wörterbuch von desc 1 und desc2 gibt, und ich weiß nicht, wie "Leute" das Ergebnis von people1 und people2 annehmen in einer einzigen Zeichenfolge

Können Sie mir helfen?

Antwort

0

Sie müssen verfolgen, ob Sie das erste Vorkommen von description innerhalb des Daten-Tags analysieren, oder das zweite. Dies kann einfach mit einem booleschen Wert (wenn es nur zwei gibt) oder mit einer ganzen Zahl (für mehrere) erfolgen, die angibt, welche der Tags Sie gerade bearbeiten. Dann können Sie in der Methode parser:didEndElement: die akkumulierten Daten basierend auf dem Flag/Zähler dem richtigen Wörterbuch zuordnen. Die andere Möglichkeit, die ich in meinem XML-Parsing verwende, besteht darin, Zeichen für ein Tag nach dem anderen zu akkumulieren. Wenn ich dann auf das schließende Element für dieses Tag stoße, dann speichere die Zeichen im Wörterbuch des entsprechenden Elements. Mit anderen Worten, wenn ich das EndTag für temp erhalte, werde ich es sofort dem aktuellen description Tag-Wörterbuch zuweisen. Wenn ich dann auf das End-Tag für das description-Tag selbst stoße, kann ich dieses Wörterbuch schließen, das Flag setzen/den Zähler inkrementieren und mit dem nächsten Tag weitermachen, das geparst werden soll.

+0

ok Ich werde deinen Vorschlag versuchen und ich werde dich wissen lassen – CrazyDev

2

ich Ihr Problem erraten ist in duplizierten Stücken von Code wie:

else if ([currentElement isEqualToString:@"temp"]){ 
    [temp1 appendString:string]; 
} 
else if ([currentElement isEqualToString:@"temp"]){ 
    [temp2 appendString:string]; 
} 

In diesem Fall Ihr erster Teil des Codes ausgeführt wird zweimal und die zweite nie.

Überprüfen Sie auch andere Teile Ihres Codes, yo haben mehrere Blöcke mit diesem Problem.

+0

Dies ist nicht korrekt, es wird nicht zweimal ausgeführt, das zweite 'else if' wird nie ausgeführt, daher die leeren Elemente. – Tark

+0

@Tark, danke. Aber der erste Teil des Codes wird in jedem Fall twiced ausgeführt - siehe xml. – beryllium

+0

dann, wie kann ich mein Problem lösen? – CrazyDev

Verwandte Themen