Strong Like Bull
Strong Like Bull

Reputation: 11297

How can I set up my object properly using NSXMLParser?

What I am trying to do is for the parser to go over each row of XML and then assign the elements to an object. At the end of the row, the object is added to a NSMutableString. I just want one faxRecipient object to be set up per one row of XML.

Here is a sample out put of the XML:

<ContactId>23</ContactId><Name>name1</Name><Fax>+12345222</Fax><Company /><Rec>0</Rec><ContactId>24</ContactId><Name>name2</Name><Fax>+78903333</Fax><Company /><Rec>0</Rec> 

My code however is buggy and I am not sure where to go from here:

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

    if ([elementName isEqual:@"ContactId"]) {
        faxRecipient =[[FaxRecipient alloc]init];
        remoteRecipientString = [[NSMutableString alloc]init]; 
    }

    else if ([elementName isEqual:@"Name"]) {
        faxRecipient =[[FaxRecipient alloc]init];
        remoteRecipientString = [[NSMutableString alloc]init]; 


    }else if ([elementName isEqual:@"Fax"]) {
        faxRecipient =[[FaxRecipient alloc]init];
        remoteRecipientString = [[NSMutableString alloc]init];
    }
    else if ([elementName isEqual:@"Company"]) {
    faxRecipient =[[FaxRecipient alloc]init];
    remoteRecipientString = [[NSMutableString alloc]init];
    }

}

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

    [remoteRecipientString appendString:string];

}


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


    if ([elementName isEqual:@"ContactId"]) {
        faxRecipient.contactID = remoteRecipientString;
        [remoteRecipientItems addObject:faxRecipient];
        [faxRecipient release];
        faxRecipient = nil;
        [remoteRecipientString release];
        remoteRecipientString = nil;
    }


    if ([elementName isEqual:@"Name"]) {
        faxRecipient.name = remoteRecipientString;
        [remoteRecipientItems addObject:faxRecipient];
        [faxRecipient release];
        faxRecipient = nil;
        [remoteRecipientString release];
        remoteRecipientString = nil;
    }   


    if ([elementName isEqual:@"Fax"]) {
        faxRecipient.fax = remoteRecipientString;
        [remoteRecipientID addObject:faxRecipient];
        [remoteRecipientString release];
        remoteRecipientString = nil;
        [faxRecipient release];
        faxRecipient = nil;
    }

    if ([elementName isEqual:@"Company"]) {
        faxRecipient.company = remoteRecipientString;
        [remoteRecipientID addObject:faxRecipient];
        [remoteRecipientString release];
        remoteRecipientString = nil;
        [faxRecipient release];
        faxRecipient = nil;
    }


}

Upvotes: 2

Views: 280

Answers (3)

RyanG
RyanG

Reputation: 4503

If you are only reading data I suggest using TBXML to parse, as it is very quick and much easier to use than NSXMLParser (imo).

Here is one of my parsing methods where I am taking the text from the elements and giving them to an object:

- (void)parseWeekEvents
{    
TBXML *tbxml;
TBXMLElement *rootXMLElement;
TBXMLElement *node_channel;
TBXMLElement *node_item;
TBXMLElement *node_traverse;

NSString *fullEventURL;
fullEventURL = @"http://www.millersville.edu/calendar/rss.php?q=&c=&date=01-06-2011&mode=index";

self.eventsDict = [[NSMutableDictionary alloc] init];
self.datesArray = [[NSMutableArray alloc] init];
[eventsDict release];
[datesArray release];

tbxml = [TBXML tbxmlWithURL:[NSURL URLWithString:fullEventURL]];
rootXMLElement = tbxml.rootXMLElement;

if(rootXMLElement)
{
    node_channel = [TBXML childElementNamed:@"channel" parentElement:rootXMLElement];

    if(node_channel)
    {
        node_item = [TBXML childElementNamed:@"item" parentElement:node_channel];

        while(node_item)
        {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

            EventArticleObject *currentEvent = [[[EventArticleObject alloc] init] autorelease];

            NSString *title;
            NSString *link;
            NSString *date;

            node_traverse = [TBXML childElementNamed:@"title" parentElement:node_item];
            title = [TBXML textForElement:node_traverse];

            [currentEvent setTitle:title];

            node_traverse = [TBXML childElementNamed:@"link" parentElement:node_item];
            link = [TBXML textForElement:node_traverse];
            [currentEvent setLink:link];

            node_traverse = [TBXML childElementNamed:@"description" parentElement:node_item];
            description = [TBXML textForElement:node_traverse];
            [currentEvent setDescription:description];

            node_traverse = [TBXML childElementNamed:@"pubDate" parentElement:node_item];
            date = [TBXML textForElement:node_traverse];

            if(![datesArray containsObject:date])
            {
                [datesArray addObject:date];
            }

            NSString *eventDate = [currentEvent date];
            NSMutableArray  *temp = [eventsDict objectForKey:eventDate];
            if(!temp)
            {
                temp = [NSMutableArray array];
                [temp addObject:currentEvent];
                [eventsDict setObject:temp forKey:eventDate];
            } else {
                [temp addObject:currentEvent];
            }
            node_item = node_item -> nextSibling;

            [pool drain];
        }
    }
    }
}

Hope this helps, let me know if you have any questions.

Upvotes: 1

CodeGuru
CodeGuru

Reputation: 301

Does your XML pass back a top level element name such as:

<FaxRecipient><ContactId>23</ContactId><Name>name1</Name><Fax>+12345222</Fax><Company /><Rec>0</Rec><ContactId>24</ContactId><Name>name2</Name><Fax>+78903333</Fax><Company /><Rec>0</Rec>  </FaxRecipient>

If yes, then you should be checking for that beginning element in your didStart and in your DidEnd such as:

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *) elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"FaxRecipient"] )
    {
    faxRecipient =[[FaxRecipient alloc]init];
    }
else if ([elementName isEqualToString:@"ContactId"] ||
         [elementName isEqualToString:@"Name"] ||
                     [elementName isEqualToString:@"Fax"] ||
         [elementName isEqualToString:@"Company"])
{
remoteRecipientString = [[NSMutableString alloc]init];
}
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *) elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqual:@"FaxRecipient"])
    {
    [remoteRecipientItems addObject:faxRecipient];
    [faxRecipient release];
    faxRecipient = nil;
    }
else if ([elementName isEqual:@"ContactId"]) {
    faxRecipient.contactID = remoteRecipientString;
}
else if ([elementName isEqual:@"Name"]) {
    faxRecipient.name = remoteRecipientString;
}
else if ([elementName isEqual:@"Fax"]) {
    faxRecipient.fax = remoteRecipientString;
}
else if ([elementName isEqual:@"Company"]) {
    faxRecipient.company = remoteRecipientString;
} 

if ([elementName isEqualToString:@"ContactId"] ||
    [elementName isEqualToString:@"Name"] ||
    [elementName isEqualToString:@"Fax"] ||
    [elementName isEqualToString:@"Company"] )
{
[remoteRecipientString release];
    remoteRecipientString = nil;    }  
}

If not, then you will need to check that you are about to parse the first element (ContactId) and do the additional initialization in didStartElement there. Then in DidEndElement do the addobject when you have just found the last element (Rec). It would be best if your XML was structured in a way that you could identify the objects that it is returning and not just hard code based on current position of the elements in the returned XML.

Upvotes: 1

Aman Aggarwal
Aman Aggarwal

Reputation: 3754

Alloc your nsmutablestring in viewdidload method and then append string to this nsmutablestring

Upvotes: 0

Related Questions