NSXMLParser从XML标记中检索错误的数据

我读了一些字段的XML,例如:

<url>http://myurl.com/noticias/redirect.html?document=xx222&usuario=44yyy&url=http%3A%2F%2Fwww.environmental-expert.com%2FresultEachPressRelease.aspx%3Fcid%3D23745%26codi%3D234441%26lr%3D1</url> <title>The world water report – supplies falling, Tensions Rising</title> 

输出是:

 2011-04-28 17:08:02.191 MyProject[12093:207] doc found 2011-04-28 17:08:02.192 MyProject[12093:207] url=http%3A%2F%2Fwww.environmental-expert.com%2FresultEachPressRelease.aspx%3Fcid%3D23745%26codi%3D234441%26lr%3D1 2011-04-28 17:08:02.193 MyProject[12093:207] – supplies falling, Tensions Rising 

这与xml文件中的数据不匹配。

我的parsing器有以下方法:

 // Start of element - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"document"]){ NSLog(@"doc found"); } } // Found Character - (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string { currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; } // End Element - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:@"url"]){ NSLog(@"%@", currentNodeContent); } if ([elementName isEqualToString:@"title"]){ NSLog(@"%@", currentNodeContent); } if ([elementName isEqualToString:@"document"]){ [currentNodeContent release]; currentNodeContent = nil; } } 

它可以关联到函数foundCharacters?

在此先感谢您的帮助!

foundCharacters可以被多次调用一个字段! 您应该创build一个临时NSMutableString并追加foundcaracters结果!

 // Start of element - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"document"]){ NSLog(@"doc found"); if (temp != nil) { [temp release]; } // Alloc temp string currentNodeContent = [[NSMutableString alloc] init]; } } // Found Character - (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string { if (currentNodeContent != nil) { [currentNodeContent appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; } } // End Element - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:@"url"]){ NSLog(@"%@", currentNodeContent); } if ([elementName isEqualToString:@"title"]){ NSLog(@"%@", currentNodeContent); } if ([elementName isEqualToString:@"document"]){ [currentNodeContent release]; currentNodeContent = nil; } // Release temp string [currentNodeContent release]; currentNodeContent = nil; } 

一定要将currentNodeContent声明为NSMutableString而不是NSString!

这里是我在我的项目中使用的XMLparsing器代码:

 // // XMLParser.h // #import <Foundation/Foundation.h> #import "XMLNode.h" #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2 @interface XMLParser : NSObject <NSXMLParserDelegate> { #else @interface XMLParser : NSObject { #endif XMLNode *rootElement; XMLNode *tempElement; NSMutableString *temp; NSMutableArray *elements; } - (NSObject *)parseData:(NSData *)data; // NSXMLParser delegate implementation - (void)parserDidStartDocument:(NSXMLParser *)parser; - (void)parserDidEndDocument:(NSXMLParser *)parser; - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict; - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName; - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string; @end 

 // // XMLParser.m // #import "XMLParser.h" @implementation XMLParser - (NSObject *)parseData:(NSData *)data { NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; [parser setDelegate:self]; [parser setShouldResolveExternalEntities:YES]; if (![parser parse]) { if ([[parser parserError] code] == NSXMLParserUnknownEncodingError) { // If encoding is "us-ascii" replace encoding with something known (as NSXMLParser is not supporting this encoding) NSString *oldString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSString *newEncodingString = [oldString stringByReplacingOccurrencesOfString:@"encoding=\"us-ascii\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)]; newEncodingString = [newEncodingString stringByReplacingOccurrencesOfString:@"encoding=\"windows-1251\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)]; [oldString release]; NSData *nameData = [newEncodingString dataUsingEncoding:NSASCIIStringEncoding]; NSXMLParser *parser2 = [[NSXMLParser alloc] initWithData:nameData]; [parser2 setDelegate:self]; [parser2 setShouldResolveExternalEntities:YES]; if (![parser2 parse]) { DLog(@"parseXML error : %@",[[parser2 parserError] localizedDescription]); } [parser2 release]; } else { DLog(@"parseXML error : %@",[[parser parserError] localizedDescription]); } } [parser release]; return rootElement; } - (void)dealloc { if (tempElement != nil) { [tempElement release]; } if (rootElement != nil) { [rootElement release]; } if (temp != nil) { [temp release]; } if (elements != nil) { [elements release]; } [super dealloc]; } // NSXMLParser delegate implementation - (void)parserDidStartDocument:(NSXMLParser *)parser { if (elements != nil) { [elements release]; } elements = [[NSMutableArray alloc] init]; if (tempElement != nil) { [tempElement release]; tempElement = nil; } if (temp != nil) { [temp release]; temp = nil; } if (rootElement != nil) { [rootElement release]; rootElement = nil; } } - (void)parserDidEndDocument:(NSXMLParser *)parser { if (elements != nil) { [elements release]; elements = nil; } if (tempElement != nil) { [tempElement release]; tempElement = nil; } if (temp != nil) { [temp release]; temp = nil; } } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { XMLNode *element = [[[XMLNode alloc] initWithName:elementName] autorelease]; [element setAttributes:attributeDict]; if (tempElement != nil) { [tempElement addChild:element]; [elements addObject:tempElement]; [tempElement release]; } else { rootElement = [element retain]; } tempElement = [element retain]; if (temp != nil) { [temp release]; } temp = [[NSMutableString alloc] init]; } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { [tempElement setContent:temp]; [temp release]; temp = nil; [tempElement release]; tempElement = nil; if ([elements count] > 0) { tempElement = [[elements lastObject] retain]; [elements removeLastObject]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if (temp != nil) { [temp appendString:string]; } } @end 

 // // XMLNode.h // #import <Foundation/Foundation.h> /** * XMLNode represents an XML data node. * * Every node can contain multiple children, attributes, a content string * and an element name. An XML document is represented using a reference * to the document root node. * @ingroup Webservice */ @interface XMLNode : NSObject { NSMutableArray *children; NSDictionary *attributes; NSString *content; NSString *elementName; } /** * Return an initialized XMLNode. * @param name The element name of the node. */ - (id)initWithName:(NSString *)name; /** * Set the node attributes. * @param dictionary A dictionary containing the attributes. */ - (void)setAttributes:(NSDictionary *)dictionary; /** * Set the content as string. * @param string The content as string. */ - (void)setContent:(NSString *)string; /** * Add a child node. * @param xmlElement The child node. */ - (void)addChild:(XMLNode *)xmlElement; /** * Return a specific attribute. * @param name The attribute name. * @return The attribute for the specified name or nil. */ - (NSString *)attributeForName:(NSString *)name; /** * Return a child at a specific index. * * If the index is out of the bounds, an NSRangeException is thrown. * @param index The position of the child (by document order). * @return The child at index * @see childElementsCount */ - (XMLNode *)childElementAtIndex:(int)index; /** * Return a child with a certain name. * @param name The name of the element. * @return The element or nil if not available. */ - (XMLNode *)childWithName:(NSString *)name; - (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index; /** * Return the number of child nodes. * @return The number of child nodes. */ - (int)childElementsCount; - (int)childWithNameElementsCount:(NSString *)name; /** * Return the node content. * @return The node content as string. */ - (NSString *)content; /** * Get the name of the xml element. * @return The name of the element. */ - (NSString *)name; - (void)dealloc; @end 

 // // XMLNode.m // #import "XMLNode.h" @implementation XMLNode - (id)initWithName:(NSString *)name { self = [super init]; elementName = [name copy]; children = [[NSMutableArray alloc] init]; return self; } - (void)setAttributes:(NSDictionary *)dictionary { if (attributes != nil) { [attributes release]; } attributes = [dictionary retain]; } - (void)setContent:(NSString *)string { if (content != nil) { [content release]; } content = [string retain]; } - (void)addChild:(XMLNode *)xmlElement { [children addObject:xmlElement]; } - (NSString *)attributeForName:(NSString *)name { return [attributes objectForKey:name]; } - (XMLNode *)childElementAtIndex:(int)index { return [children objectAtIndex:index]; } - (XMLNode *)childWithName:(NSString *)name { int i; for (i=0; i < [children count]; ++i) { XMLNode *child = [children objectAtIndex:i]; if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) { return child; } } return nil; } - (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index { int i; int count = 0; for (i = 0; i < [children count]; ++i) { XMLNode *child = [children objectAtIndex:i]; if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) { if (count == index) return child; count ++; } } return nil; } - (int)childElementsCount { return [children count]; } - (int)childWithNameElementsCount:(NSString *)name { int i; int count = 0; for (i = 0; i < [children count]; ++i) { XMLNode *child = [children objectAtIndex:i]; if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) { count ++; } } return count; } - (NSString *)content { return content; } - (NSString *)name { return elementName; } - (void)dealloc { if (content != nil) { [content release]; } if (children != nil) { [children release]; } if (attributes != nil) { [attributes release]; } [super dealloc]; } @end 

使用这个如下(这个例子是分析一个RSS饲料:

 XMLParser *parser = [[XMLParser alloc] init]; NSObject *rss = [parser parseData:rssFeed]; feedItems = [(XMLNode *)rss childWithName:@"channel"]; if (feedItems) { NSLog(@"%@",[[feedItems childWithName:@"title"] content]); } [parser release]; 

如果需要更复杂的分析,请检查XMLNode.h以获取更多方法