简体   繁体   中英

NSxml parser upto 3 levels on iphone

i have a issue getting the value of A->1,2,3,4 & b->1,2,3,4

i have to show these data on 3 tables

table 1) A , B table 2)when user click on A -> he can see 1,2,3,4 in tablular form but i my case i can only show the last value of A ie 4 ( not 1,2,3)

how to parse all 1,2,3,4

<?xml version="1.0" encoding="UTF-8"?>
<hall>
<movie Name="A">
<stall Name="1">
<description>qwe.</description>
<rating>5</rating>
</stall>
<stall Name="2">
<description>wer.</description>
<rating>5</rating>
</stall>
<stall Name="3">
<description>wer.</description>
<rating>5</rating>
</stall>
<stall Name="4i">
<description>wer.</description>
<rating>5</rating>
</stall>
</movie >
<movie Name="B">
<stall Name="t1">
<description>wer.</description>
<rating>5</rating>
</stall>
<stall Name="2">
<description>wer.</description>
<rating>5</rating>
</stall>
<stall Name="3">
<description>wer.</description>
<rating>5</rating>
</stall>
<stall Name="4">
<description>wer.</description>
<rating>5</rating>
</stall>
</movie>
</hall>
#

UPDATES

#

my problem is i dont know how to separate Movie name A and B data

 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { if([elementName isEqualToString:@"hall"]) { movieList = [[NSMutableDictionary alloc]init]; appDelegate.books = [[NSMutableArray alloc]init]; appDelegate.HospN = [[NSMutableArray alloc]init]; } else if([elementName isEqualToString:@"movie"]) { currentMovie = [[NSString alloc] initWithString:[attributeDict objectForKey:@"Name"]] ; [appDelegate.books addObject:[attributeDict objectForKey:@"Name"]]; //[aBook.movie addObject:[attributeDict objectForKey:@"Name"]]; NSLog(@"Processing Value: %@", currentMovie); //aBook.testament=currentMovie; aBook.stall = [attributeDict objectForKey:@"name"]; NSLog(@"Movie A name : %@",[movieList objectForKey:@"A"]); } else if([elementName isEqualToString:@"stall"]) { [appDelegate.HospN addObject:[attributeDict objectForKey:@"Name"]]; NSLog(@"Processing stall Value: %@", currentElementValue); NSLog(@"appDelegate.HospN: %@", appDelegate.HospN); } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if(!currentElementValue) currentElementValue = [[NSMutableString alloc] initWithString:string]; else [currentElementValue appendString:string]; //NSLog(@"Processing Value: %@", currentElementValue); } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if([elementName isEqualToString:@"hall"]) { //NSLog(@"Movie List : %@",movieList); } else if([elementName isEqualToString:@"movie"]) { [movieList setObject:appDelegate.books forKey:currentMovie]; NSLog(@"Movie name : %@",appDelegate.books ); NSLog(@"Movie A name : %@",[movieList objectForKey:@"A"]); [currentMovie release]; //[stallNames release]; currentMovie = nil; //stallNames = nil; } else if([elementName isEqualToString:@"stall"]) { //you can populate other attributes here if stall is not just string but a modal class. } else [aBook setValue:currentElementValue forKey:elementName]; [currentElementValue release]; currentElementValue = nil; } 

my array my appDelegate.HospN: value is ( 1, 2, 3, 4i, t1, 2, 3, 4 ) **but i want to chop data at A= 1,2,3,4i

and B= t1,2,3,4**

Updtate

how to get the value of description and rating ??

 else if([elementName isEqualToString:@"description"]) { NSLog(@"desp List : \\n%@\\n",currentElementValue);// i can see all value but how to chop data based on A and B [movieList setObject:currentLink forKey:@"description"]; [appDelegate.despArray addObject:[movieList copy]]; NSLog(@"adding story: %@",currentLink); } else if([elementName isEqualToString:@"rating"]) { } 

By observing the xml you will find the relationship like this...

A hall can have one or more movie and Each movies can have one ore more stall.

so what you can do is.

have a instance dictionary, say movieList, and an instance array say,stallNames, and one movieName,NSString in your xml parsing class.

movieList : will have mapping of movie name with their respective stalls.(NSMutableDictionary) stallNames : will contain stalls related to particular movie.(NSMutablArray) currentMovie: will have current movie name as it would be used as key in movieList Dictionary.(NSString)

Now in startElement method ...

if([elementName isEqualToString:@"hall"])
{
    movieList = [[NSMutableDictionary alloc]init];
}
else if([elementName isEqualToString:@"movie"])
{
    currentMovie = [[NSString alloc] initWithString:[attributeDict objectForKey:@"Name"]] ;
    stallNames = [[NSMutableArray alloc]init];
}
else if([elementName isEqualToString:@"stall"])
{
    [stallNames addObject:[attributeDict objectForKey:@"Name"]];
}

in didEndElement method

if([elementName isEqualToString:@"hall"])
{
   NSLog(@"Movie List : %@",movieList);
}
else if([elementName isEqualToString:@"movie"])
{
   [movieList setObject:stallNames forKey:currentMovie];
   [currentMovie release];
   [stallNames release];
   currentMovie = nil;
   stallNames = nil;
}
else if([elementName isEqualToString:@"stall"])
{
    //you can populate other attributes here if stall is not just string but a modal class.
}

Note : as in above code posted by you , you have a Book class, and it seems it represents Movie, so what you can do is, have another property which is array type which will hold stall names. and this Book object will be added later on an array(in didEndElement when you will encounter elementName "movie"). make this array as instance variable and initialize it when you encounter "hall" tag in startElement.

UPDATE ANS (AS PER NEW CODE)

//declare following instance variables. I am leaving aBook variable because I am not sure of its use.
NSMutableDictionary *movieList;
NSMutableArray *stallArray;
NSMutableString *currentMovieKey;


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

    if([elementName isEqualToString:@"hall"])
    {
        movieList = [[NSMutableDictionary alloc]init]; // it will contain list of all the movies in the xml.
    }
    else if([elementName isEqualToString:@"movie"])
    {
        currentMovieKey =  [[NSMutableString alloc] initWithString:[attributeDict objectForKey:@"Name"]] ; // will be used for setting key for stallArray.
        stallArray= [[NSMutableArray alloc] init];  // it will contain stall names.

    }
    else if([elementName isEqualToString:@"stall"])
    {
        [stallArray addObject:[attributeDict objectForKey:@"Name"]];        
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
        [currentElementValue appendString:string];

}

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

    if([elementName isEqualToString:@"hall"])
    {
        //parsing finished...end of root tag. movieList will be the final dictionary that will have your data
        NSLog(@"Movie List : \n%@\n",movieList);
    }
    else if([elementName isEqualToString:@"movie"])
    {
        [movieList setObject:stallArray forKey:currentMovieKey];

        [currentMovieKey release];
        currentMovie = nil;
        [stallArray release];
        stallArray = nil;
    }
    else if([elementName isEqualToString:@"stall"])
    {
        //you can populate other attributes here if stall is not just string but a modal class.
    }
    //I was not sure about your else part... 

    [currentElementValue release];
    currentElementValue = nil;
}

Thanks,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM