3

Its my first experience with xmls so please don't be harsh on me if my question is low quality. I am working on app where I retrieve all data using xml files from server.

Before posting question here I read some Tutorials about xml file parsing. But when I start to implement it in my app, then I am totally confused at the point when I am trying to parse the second Xml file and so on.

Now I want to explain my app flow using some screenshot so that it become easy for everyone that what I want.

  1. First view
  2. Second view
  3. Third view

Now when I click in any row in first view it goes to second view and show all related data in second view and when I click any item in Second view it goes to the third view and show detail information about that particular item.

After explanation of app flow, now I show my code what I tried so far. Following a tutorial I just simply drag classes (XMLParser, Book) to my app for testing purpose.

Code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
    NSLog(@"No Errors");
else
    NSLog(@"Error Error Error!!!");
 }

Now my XMLParser.m code is

- (XMLParser *) initXMLParser {

[super init];

appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

return self;
  }

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

if([elementName isEqualToString:@"Collections"]) {
    //Initialize the array.
    appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:@"Collection"]) {

    //Initialize the book.
    aBook = [[Book alloc] init];

    //Extract the attribute here.
    aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

    NSLog(@"Reading id value :%i", aBook.bookID);
}

NSLog(@"Processing Element: %@", elementName);
    }

   - (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:@"Collections"])
    return;
if([elementName isEqualToString:@"Collection"]) {
    [appDelegate.books addObject:aBook];

    [aBook release];
    aBook = nil;
}
else 
    [aBook setValue:currentElementValue forKey:elementName];

[currentElementValue release];
currentElementValue = nil;
  }

Finaly my First view Class code is

    #pragma mark Table Methods

  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
return 1;
  }


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
 {
//return [tblViewData count];
return [appDelegate.books count];
 }

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
static NSString *CellIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
    cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    cell.selectionStyle=UITableViewCellSelectionStyleGray;
    cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
//cell.textLabel.text=[[tblViewData objectAtIndex:indexPath.row]
                    // stringByReplacingOccurrencesOfString:@"*" withString:@""];
   Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];

cell.textLabel.text = aBook.title;

if([deviceType isEqualToString:@"ipad"])
{
    [cell.textLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:20]];
}
//cell.textLabel.font=[UIFont fontWithName:@"Walkway_SemiBold" size:16];
return cell;
   }

After implementation of all the above Code i got the result in form of this Now at this point i confuse how can i pass my Second view xml file url and then third view url.my xml files are in this format

First xml file

 <?xml version="1.0" encoding="UTF-8"?>
<Collections> <Collection id="5"><title>Allegroo</title> </Collection>

Second xml file

 <?xml version="1.0" encoding="UTF-8"?>
 <Collection id="5"><colletciontitle>Allegroo</colletciontitle>  <weaveimage>"imageurl"   </weaveimage><Rug id="48"><Rugthumb>"firstimageurl"</Rugthumb><RugSku>AL-637</RugSku></Rug><Rug id="51"><Rugthumb>"Secondimageurl"</Rugthumb><RugSku>AL-641</RugSku></Rug>

Third xml file

  <?xml version="1.0" encoding="UTF-8"?>
 <Rug id="47"><Rugmainimage>"imageurl"</Rugmainimage> <Rugtitle>AL-636 Aged Indigo / Vintage Beige</Rugtitle> <Rugdiscription>Hand Knotted
  Distressed Wool Pile / Cotton Foundation </Rugdiscription><Availablesizes><Size>10x14</Size><Size>12x15</Size><Size>2x3</Size><Size>3x5</Size><Size>4x6</Size><Size>6x9</Size><Size>8x10</Size><Size>9x12</Size><Runner>2'6"x10'</Runner><Runner>2'6"x12'</Runner><Runner>2'6"x8'</Runner></Availablesizes></Rug>

Any help in the form of link or sample code releated to my issue and suggestion will be highly appriated.Thanks

rene
  • 41,474
  • 78
  • 114
  • 152
jamil
  • 2,419
  • 3
  • 37
  • 64
  • 1
    Simplest way is you can define an int variable and before parsing you can check the value of that variable. – Baby Groot Feb 21 '13 at 05:59
  • You are right but i confuse that how i pass multiple xml file urls in AppDelegate. – jamil Feb 21 '13 at 06:01
  • 1
    As far as i can understand ur code. i guess you don't need to parse xml in appdelegate. Either you can do that in ur viewdidload or when table row is selected. And you will have that value stored in array which you can define in AppDelegate and modify according to ur need. – Baby Groot Feb 21 '13 at 06:09
  • please post answer in detail i think your method is according to my requirement. – jamil Feb 21 '13 at 06:18

2 Answers2

2

Hmm, So Defining long story short, you want to parse multiple urls in sequence ?

So here is the answer,

  1. Use a variable / identifier in appDelegate that tells you which xml is being parsed.
  2. Use your xml parser as delegate class object
  3. Use delegate method to swich to next xml parsing

     - (void)parserDidEndDocument:(NSXMLParser *)parser {
         // Change URL accordingly 
         NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
         NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
         XMLParser *parser = [[XMLParser alloc] initXMLParser];
         [xmlParser setDelegate:parser];
          BOOL success = [xmlParser parse];
    }
    
DivineDesert
  • 6,924
  • 1
  • 29
  • 61
  • 1
    thanks for your answer but please can you simplfy your answer for me as i said my first url working and it show data in tableview now i want when i click in any row of uitableview it show data in second view using second url. – jamil Feb 21 '13 at 09:12
1

I have added some of the code to make you understand. Try to implement according to your condition. Below code is just to refer as i havn't made all the changes u need to understand first and then implement accordingly

//int i = 0;   // in AppDelegate

Code:

//Or ViewDidLoad Method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 int = 1;    //For First View
NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
    NSLog(@"No Errors");
else
    NSLog(@"Error Error Error!!!");
 }

XMLParser.m

- (XMLParser *) initXMLParser 
    {  
      [super init];
      appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
      return self;
    }

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

    if([elementName isEqualToString:@"Collections"]) 
   {
        //Initialize the array.
      if (int == 1)
        appDelegate.books = [[NSMutableArray alloc] init];

      else if (int == 2)
        appDelegate.secondArray = [[NSMutableArray alloc] init];

      else if (int == 3)
        appDelegate.thirdArray = [[NSMutableArray alloc] init];
    }

    else if([elementName isEqualToString:@"Collection"]) 
  {
         if (i == 1)
        {
          //Initialize the book.
          aBook = [[Book alloc] init];

          //Extract the attribute here.
          aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

          NSLog(@"Reading id value :%i", aBook.bookID);
        }

         else if (i == 2)
        {
           //Second Xml 
        }

        else if (i == 3)
       {
           //Third Xml
       }

    }

  NSLog(@"Processing Element: %@", elementName);
 }


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    //Check condition 
    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 {
//Check COndition
    if([elementName isEqualToString:@"Collections"])
        return;
    if([elementName isEqualToString:@"Collection"]) {
        [appDelegate.books addObject:aBook];

        [aBook release];
        aBook = nil;
    }
    else 
        [aBook setValue:currentElementValue forKey:elementName];

    [currentElementValue release];
    currentElementValue = nil;
      }
rohan-patel
  • 5,772
  • 5
  • 45
  • 68
Baby Groot
  • 4,637
  • 39
  • 52
  • 71
  • hi when i call the url in viewdidload it not show any data in tableview i think viewdidload and tableview delegate method call at the same time thats why its show my book array empty. – jamil Feb 21 '13 at 09:22
  • Make sure that you are reloading table after parsing [tableView reloadData]; and check the value in array also whether it has data or not once parsing is complete. – Baby Groot Feb 21 '13 at 09:24
  • http://paste.ubuntu.com/1698042/ please check my code my book array show null data. – jamil Feb 21 '13 at 09:37
  • 1
    books array that you are showing is an object of this class, while you are paring xml in some other class. Are you storing value in this object or this class? i m not sure. Better you define that array in AppDelegate. – Baby Groot Feb 21 '13 at 09:42
  • oh really so big mistak after define array in appDelegate now first view show data.let me try now for secondview.can i chat with you any Discussion Group beacuse in second view i have complex xml file so i need little help..please i will be gratefull. – jamil Feb 21 '13 at 09:50
  • int concept is not working please can you explain it i used it according to your coding but still not working. – jamil Feb 21 '13 at 10:20
  • But still parsing of second xml file looks extremly difficult..beacuse i need to compare it with the first xml item which one is click,so on the base of it i need show data in second view. – jamil Feb 21 '13 at 11:00
  • 1
    u seem to be new not only to xml but xcode also. You want data according to selection that's y u need to alloc array of second class in ur first class in tableview didselectrow. – Baby Groot Feb 21 '13 at 11:03
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24891/discussion-between-bob-apple-and-smriti-yadav) – jamil Feb 21 '13 at 11:09