IOS: NSMXLParser с несколькими узлами - PullRequest
0 голосов
/ 02 апреля 2012

У меня есть файл xml:

<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 есть пробел, и я не знаю, как «люди» воспринимают результат people1 и people2 в одной строке

Можете ли выпомогите мне?

Ответы [ 2 ]

2 голосов
/ 02 апреля 2012

Полагаю, ваша проблема в дублированных кусках кода, таких как:

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

В этом случае ваша первая часть кода будет выполняться дважды, а вторая никогда.

Проверьте также другие части вашего кода, у вас есть несколько блоков с этой проблемой.

0 голосов
/ 02 апреля 2012

Вам необходимо отслеживать, анализируете ли вы первое вхождение description в теге данных или второе.Это можно легко сделать с помощью логического (если есть только два) или целого числа (для нескольких), которое указывает, какой из тегов вы сейчас обрабатываете.Затем в методе parser:didEndElement: вы можете назначить накопленные данные правильному словарю на основе флага / счетчика.

Другая возможность, которую я использую при анализе XML, - это накопление символов дляза раз, затем, когда я сталкиваюсь с закрывающим элементом для этого тега, сохраняем символы в Словаре содержащего элемента прямо тогда.Другими словами, когда я сталкиваюсь с endTag для temp, я немедленно назначу его в словарь текущего тега description.Затем, когда я сталкиваюсь с конечным тегом для самого тега description, я могу закрыть этот словарь, установить флаг / увеличить счетчик и продолжить со следующим тегом, который должен быть проанализирован.

...