XML:解析节点内的嵌套节点并按节分开

时间:2011-11-21 14:06:44

标签: iphone objective-c ios xml uitableview

我有以下XML模式,我正在尝试迭代:

<routes>
     <route>
          <group>Group Name - Will be iPhone section name</group>
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>
     </route>
   <route>
          <group>Group 2 - Will be iPhone section name</group>
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>         
          <item>
                <name>Route Name - Will be iphone cell lable</name>
                <url>Route URL - View Did select lable</url>
          </item>
     </route>
</routes>

现在,他们中的大多数都在项目中有相当多的条目 - 而Group节点将是UITableView的部分标题

这是我现在如何解析(错误地)XML:

(这是xNode_声明:)

static NSString *xNode_route =@"//route";
static NSString *xNode_group =@"group";
static NSString *xNode_item= @"//item";
static NSString *xNode_name = @"name";
static NSString *xNode_url = @"url";

这是解析代码:

    CXMLDocument *doc = [[CXMLDocument alloc] initWithData:dataReply options:0 error:nil];
    NSArray *route = [doc nodesForXPath:xNode_route error:nil];//Root node
    for (CXMLElement *item in route) 
    {
        AssessObject *newobj2 = [[AssessObject alloc] init];
        NSArray *arryGroup = [item elementsForName:xNode_group];
        for(CXMLElement *assGroup in arryGroup) 
        {

            newobj2.assGroup = assGroup.stringValue;
            NSLog(@"Assessment Group: %@", assGroup.stringValue);

        }   

        [groupArray addObject:newobj2];


    }

    NSArray *items = [doc nodesForXPath:xNode_item error:nil];//Root node
    for (CXMLElement *item in items) 
    {
        AssessObject *newobj = [[AssessObject alloc] init];
        NSArray *arryName = [item elementsForName:xNode_name];
        for(CXMLElement *assName in arryName) 
        {

            newobj.assName = assName.stringValue;
            NSLog(@"Assessment Name: %@", assName.stringValue);

        }

        NSArray *arryUrl = [item elementsForName:xNode_url];
        for(CXMLElement *assUrl in arryUrl) 
        {

            newobj.assUrl = assUrl.stringValue;
            NSLog(@"Assessment URL: %@", assUrl.stringValue);


        }

            [totalArray addObject:newobj];
    }
}   

目前它正在经历所有项目x组的数量,因此循环在某处不正确。因此,如果有6个组,它会显示6次项目的副本。

那么这是第一部分,第二部分真的是如何将数组分成组并在其中包含正确的项目?

1 个答案:

答案 0 :(得分:0)

首先,您没有正确释放内存。

在发布的代码中有6个发布语句 - 将它们全部删除。

然后,您需要添加两个语句:

 [release newObj2];

为您明确分配的对象:newObj和newObj2,在您将它们添加到数组之后。

然后,如果事情不起作用,我们可以谈谈解析。

编辑: 好的,让我们谈谈解析:

+ (NSMutableArray *) parseResponseString:(NSString *) responseString {
NSError *error;
CXMLDocument *doc = [[CXMLDocument alloc] initWithXMLString: responseString
                                                    options: 0
                                                      error: &error];
if ( error ) {
    NSLog(@"CXMLDocument error: %@", [error description]);
    [doc release];
    return nil;
} 


CXMLElement * el = [doc rootElement];
NSMutableArray *theRoutes = [NSMutableArray arrayWithCapacity:128];  // adjust to your needs

if ( [[el name] isEqualToString:@"routes"] ) {                       // parameterize these string constants
    for ( CXMLElement *childElement in [el children] ) {
        if ( [[childElement name] isEqualToString:@"route"] ) {
            Route *aRoute = [[Route alloc] init];

            for ( CXMLElement *grandChild in [childElement children] ) {
                if ( [[grandChild name] isEqualToString:@"group"] ) {
                    aRoute.group = [grandChild stringValue];
                } else if ( [[grandChild name] isEqualToString:@"item"] ) {
                    RouteItem *aRouteItem = [[RouteItem alloc] init];

                    for ( CXMLElement *subItem in [grandChild children] ) {
                        if ( [[subItem name] isEqualToString:@"name"] ) {
                            aRouteItem.name = [subItem stringValue];
                        } else if ( [[subItem name] isEqualToString:@"url"] ) {
                            aRouteItem.url = [subItem stringValue];
                        }
                    }

                    if ( aRouteItem && aRouteItem.name && aRouteItem.url ) {
                        [aRoute.routeItems addObject:aRouteItem];
                    }
                    [aRouteItem release];
                }
            }

            if ( aRoute && aRoute.group && aRoute.items.count ) {
                [theRoutes addObject:aRoute];
            }
            [aRoute release];
        }
    }
}
[doc release];
return theRoutes;   // this is your array for your tableview data source.

}