0

In my application i parse a xml from which I get a list of items (hotels and restaurants) that i put into array "listElements"; I need to get from this array, another array that will contain only the particular elements (hotels only) and then I need to get from this array, three array that will contain hotels according to stars(array5starhotel, array4starhotel,array3starhotel). How can do this? This is the code I used for parsing(I used TBXML):

- (void)loadCategories {
    // instantiate an array to hold categories objects
    listCategories = [[NSMutableArray alloc] initWithCapacity:100];

    tbxml = [[TBXML tbxmlWithXMLFile:@"Molise.xml"] retain];

    // Obtain root element
    TBXMLElement * root = tbxml.rootXMLElement;

    // if an author element was found
    if (root) {
      //search for the first category element within the root element's children
      TBXMLElement * category = [TBXML childElementNamed:@"category" parentElement:root];

      // if a category element was found
      while (category != nil) {

        // instantiate a category object
        Category * aCategory = [[Category alloc] init];

        // get the name attribute from the category element
        aCategory.name = [TBXML valueOfAttributeNamed:@"name" forElement:category];

        // search the category's child elements for a "element" element
        TBXMLElement * element = [TBXML childElementNamed:@"element" parentElement:category];

        // if a "element" element was found     
        while (element != nil) {                              

          // instantiate a "element" object
          Element * aElement = [[Element alloc] init];

          // extract the attributes from the "element" element
          aElement.title = [TBXML valueOfAttributeNamed:@"title" forElement:element];
          aElement.address = [TBXML valueOfAttributeNamed:@"address" forElement:element];          
          aElement.stars =[TBXML valueOfAttributeNamed:@"stars" forElement:element];

          // add the "element" object to the category's listElements array and release the resource       
          [aCategory.listElements addObject:aElement];
          [aElement release];

          // find the next sibling element named "element"
          element = [TBXML nextSiblingNamed:@"element" searchFromElement:element];
        }

        // add our category object to the listCategories array and release the resource  
        [listaCategories addObject:aCategory];
        [aCategory release];

        // find the next sibling element named "category"
        category = [TBXML nextSiblingNamed:@"category" searchFromElement:category];
      }                      

      [tbxml release];
    }

2 Answers 2

1

OK, so your code snippet doesn't do what the question says it does.

You make an array of categories (listCategories) containing lots of Category objects. Each of these contains a listElements array.

Assuming that you want the items from the 'hotels' category . . .

// Get the hotels category
Category *hotelsCategory = nil;
for (Category *temp in listCategories.each) {
  if ([temp.name isEqualToString:@"hotel"]) {
    hotelsCategory = temp;
    break;
  }
}
if (nil == hotelsCategory)
  return NSLog(@"No hotels category found");

// Get the hotels from this category with a 3 or above star rating
NSMutableArray *array5starhotel = [NSMutableArray array];
NSMutableArray *array4starhotel = [NSMutableArray array];
NSMutableArray *array3starhotel = [NSMutableArray array];
for (Element *element in hotelsCategory.listElements) {
  if ([element.stars isEqualToString:@"5"])
    [array5starhotel addObject:element];
  if ([element.stars isEqualToString:@"4"])
    [array4starhotel addObject:element];
  if ([element.stars isEqualToString:@"3"])
    [array3starhotel addObject:element];
}

Hope that helps - I've had to guess at some stuff because I don't know what's in a Category or Element object!

Sign up to request clarification or add additional context in comments.

3 Comments

I'll explain better in the class Category are instantiated a string "name" (category.name) and an array listElement (category.listElement); in the class Element are instantiated three strings: title, description, stars (element.title, element.stars element.description.) The reason why I asked how to make the three arrays is that when I click on the hotel category I need to display the hotels according to stars in three different section of a tableView
OK, the second part of my code will go through a single Category object and get the three arrays that you want.
dean i have a problem with your code, in three array is loaded always the same hotel (the first of XML tree),in fact in the three sections of the table view I get the same hotel when they should appear three different
1

NSArrays [filteredArrayUsingPredicate:][1] is the tool for the job.

As noted, your listCategories array will contain an array of Category objects with each category containing an array of Element objects.

// Retrieve "hotel" Elements 

NSPredicate *hotelPredicate = [NSPredicate predicateWithFormat:@"name == hotel"];
Category *hotelCategory = [[[listCategories filteredArrayUsingPredicate:hotelPredicate] objectAtIndex: 0] retain];

NSArray *hotels = [[hotelCategory listElements] retain];

// Split the array of Elements based on star value
NSPredicate *elementRatingTemplate = [NSPredicate predicateWithFormat:@"stars == $STARS"];

NSPredicate *threeStarPredicate = [elementRatingTemplate predicateWithSubstitutionVariables: [NSDictionary dictionaryWithObject:@"3" forKey:@"STARS"];

NSArray *threeStarHotels = [[hotels filteredArrayUsingPredicate: threeStarPredicate] retain]; 

NSPredicate *fourStarPredicate = [elementRatingTemplate predicateWithSubstitutionVariables: [NSDictionary dictionaryWithObject:@"4" forKey:@"STARS"];

NSArray *fourStarHotels = [[hotels filteredArrayUsingPredicate: fourStarPredicate] retain]; 

NSPredicate *fiveStarPredicate = [elementRatingTemplate predicateWithSubstitutionVariables: [NSDictionary dictionaryWithObject:@"5" forKey:@"STARS"];

NSArray *fiveStarHotels = [[hotels filteredArrayUsingPredicate: fiveStarPredicate] retain]; 

// Do something with the filtered arrays
// Clean up retained objects.

4 Comments

NSPredicateTemplate doesn't exist, NSArray may not respond to listElements, error: expected ':' before 'token' and confused by earlier errors, bailing out after NSArray *threeStarHotels
thanks now I try if it works I was going to put this code at the end of parsing before [tbxml release]; then i recover the hotels from the array, in view controller
The first predicate was incorrect. I have updated to @"name == hotel"
i found another solution, but thank you very much for your help!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.