与多个节点的 IOS: NSMXLParser

标签: Xcode ios
发布时间: 2017/3/27 19:51:11
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我已经为这一文件 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,之间的空间,我不知道如何"人"把人民 1 和 people2 的结果在一个单一的字符串

你可以帮我吗?

解决方法 1:

您需要跟踪是否你正在分析的第一个匹配的 description 内的数据标记或第二。这很容易做到的 boolean 类型的值 (如果仅有两名),或一个整数 (为多),指示,你当前正在处理的标记。 然后,在 parser:didEndElement: 方法,可以将累积的数据分配给基于国旗/计数器正确的词典。

另一种可能性,我在我的 XML 解析中使用,是积累字符为一个标记一次,然后当我遇到这样的标签的结束元素存储字符到包含元素字典吧。 换句话说,当我遇到的 endTag temp ,我会立即将其分配给当前 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 ] ;
}
赞助商