如何使用NSXMLParser正确设置对象?

时间:2011-05-31 07:12:10

标签: iphone ios

我要做的是让解析器遍历XML的每一行,然后将元素分配给一个对象。在行的末尾,该对象被添加到NSMutableString。我只想在每行XML上设置一个faxRecipient对象。

以下是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> 

我的代码有问题,我不知道从哪里开始:

-(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;
    }


}

3 个答案:

答案 0 :(得分:1)

您的XML是否会传回顶级元素名称,例如:

<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>

如果是,那么你应该检查didStart和DidEnd中的那个开始元素,例如:

-(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;    }  
}

如果没有,那么您需要检查是否要解析第一个元素(ContactId)并在didStartElement中进行额外的初始化。然后在DidEndElement中,当您刚刚找到最后一个元素(Rec)时执行addobject。如果您的XML的结构能够识别它返回的对象,而不仅仅是基于返回的XML中元素的当前位置的硬代码,那将是最好的。

答案 1 :(得分:1)

如果您只是阅读数据,我建议使用TBXML进行解析,因为它比NSXMLParser(imo)更快速,更容易使用。

这是我的解析方法之一,我从元素中获取文本并将它们提供给对象:

- (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];
        }
    }
    }
}

希望这有帮助,如果您有任何问题,请与我联系。

答案 2 :(得分:0)

在viewdidload方法中分配你的nsmutablestring,然后将字符串追加到这个nsmutablestring