2012-04-01 37 views
0

我有一個文件XML作爲這樣的:IOS:NSMXLParser與多個節點

<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> 

我使用用於解析該代碼:

- (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); 
} 

的NSLog的結果是:

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

現在我不明白爲什麼在desc 1和desc2的第一個詞典之間存在一個空格,我不知道「people」如何將people1和people2的結果在單個字符串中

你能幫我嗎?

回答

0

您需要跟蹤是否解析數據標記中第一次出現description或第二次出現。這可以通過一個布爾值(如果只有兩個)或者一個整數(對於多個)來輕鬆完成,該整數指示當前正在處理哪個標記。然後,在parser:didEndElement:方法中,可以根據標誌/計數器將累積數據分配到正確的字典。

我在XML解析中使用的另一種可能性是一次累積一個標記的字符,然後當遇到該標記的閉合元素時,將字符存儲到包含元素的Dictionary右側。換句話說,當我遇到temp的endTag時,我會立即將它分配給當前的description標籤字典。然後,當我遇到description標籤本身的結束標籤時,我可以關閉該字典,設置標誌/遞增計數器,並繼續下一個要分析的標籤。

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

    if ([ elementName isEqualToString:@"description" ]) 
    { 
     curDescription = [ [ NSMutableDictionary alloc ] init ] ; 
    } 

    // ... SNIP ... 

    accumulatedCharacters = [ [ NSMutableString alloc ] init ] 
} 

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

    if ([ elementName isEqualToString:@"temp" ]) 
    { 
     [ curDescription setValue:accumulatedCharacters forKey:@"temp" ] ; 
    } 
    if ([ elementName isEqualToString:@"description" ]) 
    { 
     // Save the curDescription object, then clear it for reuse on the next 
     // occurrence of the tag 
     [ curDescription release ] ; 
     curDescription = nil ; 
    } 

    // ... SNIP ... 

    [ accumulatedCharacters release ] ; 
    accumulatedCharacters = nil ; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 
{ 
    [ accumulatedCharacters appendString:string ] ; 
} 
+0

好的我會嘗試你的建議,我會讓你知道 – CrazyDev 2012-04-02 22:59:45

2

我猜你的問題是代碼重複塊如:

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

在這種情況下從來沒有的代碼的第一部分將執行兩次和第二。

檢查你的代碼的另一部分,你有這個問題的幾個塊。

+0

這是不正確的,它不會被執行兩次,第二個'else if'永遠不會被執行,因此是空的元素。 – Tark 2012-04-01 21:06:44

+0

@Tark,謝謝。但是在任何情況下,代碼的第一部分都會被執行 - 參見xml。 – beryllium 2012-04-01 21:09:39

+0

那麼,我該如何解決我的問題? – CrazyDev 2012-04-01 21:32:14