// ResxmlParser is globally declared as NSXMLParser
-(void)parsingXML:(NSString *)resXml
{
NSData *xmlNsData =[resXml dataUsingEncoding:NSASCIIStringEncoding];
ResxmlParser = [[NSXMLParser alloc] initWithData:xmlNsData ];
[ResxmlParser setDelegate: self];
[ResxmlParser setShouldResolveExternalEntities: YES];
[ResxmlParser parse] ;
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//NSLog(@"-----------%@",string);
}
//------------------------------------------------------------------------------------
this is working fine in iPhone sdk 2.2 and lower version , but it is not working on sdk 3.0..
这在iPhone sdk 2.2和更低的版本中运行良好,但在sdk 3.0中不工作。
any body can help me to solve this problem.. ?
任何一个人都能帮助我解决这个问题。吗?
5 个解决方案
#1
1
xml parser in 3.0 is much more sensitive. it fails if can't find closing tag. for example, it won't work if you have several <br>s in your code, but will work if you change all <br>s to <br />s
3.0中的xml解析器要敏感得多。如果找不到结束标记,它将失败。例如,如果您的代码中有几个
s,那么它将不起作用,但是如果您将所有
s更改为
s,那么它将起作用
#2
1
- (void)parseXMLFileAtURL:(NSString *)URL
{
arrFilm = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:URL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(@"error parsing XML: %@", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"item"]){
currentFilm = [Film alloc];
currentNodeContent =[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:@"title"]){
currentFilm.content = currentNodeContent;
}
if([elementName isEqualToString:@"link"]){
currentFilm.Link = currentNodeContent;
}
if([elementName isEqualToString:@"description"]){
currentFilm.Description = currentNodeContent;
}
if([elementName isEqualToString:@"item"]){
[arrFilm addObject:currentFilm];
[currentFilm release];
currentFilm = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(@"all done!");
NSLog(@"stories array has %d items", [arrFilm count]);
[objtableView reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSMutableArray *arr=[xmlcont arrFilm];
return[arrFilm count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
//NSMutableArray *cont = [xmlcont arrFilm];
Film *current = [arrFilm objectAtIndex:indexPath.row];
cell.detailTextLabel.font = [UIFont systemFontOfSize:10.0];
cell.textLabel.font = [UIFont systemFontOfSize:12.0];
cell.textLabel.text = current.content;
cell.detailTextLabel.text = current.Link;
}
return cell;
}
#3
1
xmlParser = [[NSXMLParser alloc] initWithData:appListData];
[xmlParser setDelegate:self];
[xmlParser parse];
self.appListData = nil;
#4
1
You can use Yahoo RSS for xml Parsing demo as below I Pick Titles and description from RSS Item in this demo
您可以使用Yahoo RSS进行xml解析演示,如下所示,我从这个演示中从RSS项中选择标题和描述
- (void)viewDidLoad {
NSURL *url = [[NSURL alloc] initWithString:@"http://www.ibtimes.com/rss/articles/reporters/david-zielenziger.rss"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Set delegate
[xmlParser setDelegate:self];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(@"No Errors");
else
NSLog(@"Error Error Error!!!");
[super viewDidLoad];
NSLog(@"My array is %@",[arrData description]);
[tblView reloadData];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
NSLog(@"didStartElement Element:- %@",elementName);
if([elementName isEqualToString:@"rss"])
{
if(arrData ==nil)
{
arrData = [[NSMutableArray alloc] init];
}
}
else if([elementName isEqualToString:@"item"])
{
if(([dictData retainCount]>0) && dictData!=nil)
{
[dictData release];
}
dictData=[[NSMutableDictionary alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"String :- %@",string);
if(!currentElementValue)
currentElementValue = [[NSString alloc] initWithString:string];
else
//currentElementValue = [NSString stringWithString:string];
currentElementValue = [currentElementValue stringByAppendingString:string];
currentElementValue = [currentElementValue stringByReplacingOccurrencesOfString:@"\n" withString:@""];
NSLog(@"Processing Value: %@", currentElementValue);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:@"title"])
{
[dictData setValue:currentElementValue forKey:elementName];
}
else if([elementName isEqualToString:@"description"])
{
[dictData setValue:currentElementValue forKey:elementName];
}
else if([elementName isEqualToString:@"item"])
{
[arrData addObject:dictData];
}
currentElementValue = @"";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text=[[arrData objectAtIndex:indexPath.row] valueForKey:@"title"];
cell.detailTextLabel.text=[[arrData objectAtIndex:indexPath.row] valueForKey:@"description"];
return cell;
}
#5
1
There is another method for xml parsing using KMLReader. You got dictionary directly from it. you have to import these file and call dictionary For XMLData method from KMLReader file and you get parse dictionary directly from it.just import this class
还有一种使用KMLReader进行xml解析的方法。你直接从它那里得到了字典。您必须从KMLReader文件导入这些文件并调用XMLData方法的dictionary,并直接从该文件获取解析字典。进口这类
KMLReader.h
KMLReader.h
#import <Foundation/Foundation.h>
@interface KMLReader : NSObject <NSXMLParserDelegate>
{
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError **errorPointer;
}
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;
@end
@interface NSDictionary (XMLReaderNavigation)
- (id)retrieveForPath:(NSString *)navPath;
@end
KMLReader.m
KMLReader.m
#import "KMLReader.h"
NSString *const kKMLReaderTextNodeKey = @"text";
@interface KMLReader (Internal)
- (id)initWithError:(NSError **)error;
- (NSDictionary *)objectWithData:(NSData *)data;
@end
@implementation NSDictionary (KMLReaderNavigation)
- (id)retrieveForPath:(NSString *)navPath
{
// Split path on dots
NSArray *pathItems = [navPath componentsSeparatedByString:@"."];
// Enumerate through array
NSEnumerator *e = [pathItems objectEnumerator];
NSString *path;
// Set first branch from self
id branch = [self objectForKey:[e nextObject]];
int count = 1;
while ((path = [e nextObject]))
{
NSLog(@"%@",path);
// Check if this branch is an NSArray
if([branch isKindOfClass:[NSArray class]])
{
if ([path isEqualToString:@"last"])
{
branch = [branch lastObject];
}
else
{
if ([branch count] > [path intValue])
{
branch = [branch objectAtIndex:[path intValue]];
}
else
{
branch = nil;
}
}
}
else
{
// branch is assumed to be an NSDictionary
branch = [branch objectForKey:path];
}
count++;
}
return branch;
}
@end
@implementation KMLReader
#pragma mark -
#pragma mark Public methods
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer
{
NSLog(@"path :: %@",path);
//NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"xml"];
if ([path length]!=0) {
NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"kml"];
NSLog(@"full path :: %@",fullpath);
NSData *data = [[NSFileManager defaultManager] contentsAtPath:fullpath];
NSDictionary *rootDictionary = [KMLReader dictionaryForXMLData:data error:errorPointer];
NSLog(@"rootDictionary == %@",rootDictionary.description);
return rootDictionary;
}
else
{
return nil;
}
}
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
{
KMLReader *reader = [[KMLReader alloc] initWithError:error];
// NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza&zip=94306&results=1&output=xml"]];
NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.ibtimes.com/rss/articles/reporters/david-zielenziger.rss"]];
NSDictionary *rootDictionary = [reader objectWithData:data1];
[reader release];
NSLog(@"ROOT DICTIONARY :: %@",rootDictionary.description);
return rootDictionary;
}
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [KMLReader dictionaryForXMLData:data error:error];
}
#pragma mark -
#pragma mark Parsing
- (id)initWithError:(NSError **)error
{
if ((self = [super init]))
{
errorPointer = error;
}
return self;
}
- (void)dealloc
{
[dictionaryStack release];
[textInProgress release];
[super dealloc];
}
- (NSDictionary *)objectWithData:(NSData *)data
{
// Clear out any old data
[dictionaryStack release];
[textInProgress release];
dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];
// Initialize the stack with a fresh dictionary
[dictionaryStack addObject:[NSMutableDictionary dictionary]];
// Parse the XML
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
BOOL success = [parser parse];
[parser release];
// Return the stack's root dictionary on success
if (success)
{
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
return resultDict;
}
return nil;
}
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// Get the dictionary for the current level in the stack
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
// Create the child dictionary for the new element
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
// Initialize child dictionary with the attributes, prefixed with '@'
for (NSString *key in attributeDict) {
[childDict setValue:[attributeDict objectForKey:key]
forKey:[NSString stringWithFormat:@"@%@", key]];
}
// If there's already an item for this key, it means we need to create an array
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
NSMutableArray *array = nil;
if ([existingValue isKindOfClass:[NSMutableArray class]])
{
// The array exists, so use it
array = (NSMutableArray *) existingValue;
}
else
{
// Create an array if it doesn't exist
array = [NSMutableArray array];
[array addObject:existingValue];
// Replace the child dictionary with an array of children dictionaries
[parentDict setObject:array forKey:elementName];
}
// Add the new child dictionary to the array
[array addObject:childDict];
}
else
{
// No existing value, so update the dictionary
[parentDict setObject:childDict forKey:elementName];
}
// Update the stack
[dictionaryStack addObject:childDict];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// Update the parent dict with text info
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
// Pop the current dict
[dictionaryStack removeLastObject];
// Set the text property
if ([textInProgress length] > 0)
{
if ([dictInProgress count] > 0)
{
[dictInProgress setObject:textInProgress forKey:kKMLReaderTextNodeKey];
}
else
{
// Given that there will only ever be a single value in this dictionary, let's replace the dictionary with a simple string.
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
id parentObject = [parentDict objectForKey:elementName];
// Parent is an Array
if ([parentObject isKindOfClass:[NSArray class]])
{
[parentObject removeLastObject];
[parentObject addObject:textInProgress];
}
// Parent is a Dictionary
else
{
[parentDict removeObjectForKey:elementName];
[parentDict setObject:textInProgress forKey:elementName];
}
}
// Reset the text
[textInProgress release];
textInProgress = [[NSMutableString alloc] init];
}
// If there was no value for the tag, and no attribute, then remove it from the dictionary.
else if ([dictInProgress count] == 0)
{
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
[parentDict removeObjectForKey:elementName];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Build the text value
[textInProgress appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
// Set the error pointer to the parser's error object
if (errorPointer)
*errorPointer = parseError;
}
@end
#1
1
xml parser in 3.0 is much more sensitive. it fails if can't find closing tag. for example, it won't work if you have several <br>s in your code, but will work if you change all <br>s to <br />s
3.0中的xml解析器要敏感得多。如果找不到结束标记,它将失败。例如,如果您的代码中有几个
s,那么它将不起作用,但是如果您将所有
s更改为
s,那么它将起作用
#2
1
- (void)parseXMLFileAtURL:(NSString *)URL
{
arrFilm = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:URL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(@"error parsing XML: %@", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"item"]){
currentFilm = [Film alloc];
currentNodeContent =[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:@"title"]){
currentFilm.content = currentNodeContent;
}
if([elementName isEqualToString:@"link"]){
currentFilm.Link = currentNodeContent;
}
if([elementName isEqualToString:@"description"]){
currentFilm.Description = currentNodeContent;
}
if([elementName isEqualToString:@"item"]){
[arrFilm addObject:currentFilm];
[currentFilm release];
currentFilm = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(@"all done!");
NSLog(@"stories array has %d items", [arrFilm count]);
[objtableView reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSMutableArray *arr=[xmlcont arrFilm];
return[arrFilm count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
//NSMutableArray *cont = [xmlcont arrFilm];
Film *current = [arrFilm objectAtIndex:indexPath.row];
cell.detailTextLabel.font = [UIFont systemFontOfSize:10.0];
cell.textLabel.font = [UIFont systemFontOfSize:12.0];
cell.textLabel.text = current.content;
cell.detailTextLabel.text = current.Link;
}
return cell;
}
#3
1
xmlParser = [[NSXMLParser alloc] initWithData:appListData];
[xmlParser setDelegate:self];
[xmlParser parse];
self.appListData = nil;
#4
1
You can use Yahoo RSS for xml Parsing demo as below I Pick Titles and description from RSS Item in this demo
您可以使用Yahoo RSS进行xml解析演示,如下所示,我从这个演示中从RSS项中选择标题和描述
- (void)viewDidLoad {
NSURL *url = [[NSURL alloc] initWithString:@"http://www.ibtimes.com/rss/articles/reporters/david-zielenziger.rss"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Set delegate
[xmlParser setDelegate:self];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(@"No Errors");
else
NSLog(@"Error Error Error!!!");
[super viewDidLoad];
NSLog(@"My array is %@",[arrData description]);
[tblView reloadData];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
NSLog(@"didStartElement Element:- %@",elementName);
if([elementName isEqualToString:@"rss"])
{
if(arrData ==nil)
{
arrData = [[NSMutableArray alloc] init];
}
}
else if([elementName isEqualToString:@"item"])
{
if(([dictData retainCount]>0) && dictData!=nil)
{
[dictData release];
}
dictData=[[NSMutableDictionary alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"String :- %@",string);
if(!currentElementValue)
currentElementValue = [[NSString alloc] initWithString:string];
else
//currentElementValue = [NSString stringWithString:string];
currentElementValue = [currentElementValue stringByAppendingString:string];
currentElementValue = [currentElementValue stringByReplacingOccurrencesOfString:@"\n" withString:@""];
NSLog(@"Processing Value: %@", currentElementValue);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:@"title"])
{
[dictData setValue:currentElementValue forKey:elementName];
}
else if([elementName isEqualToString:@"description"])
{
[dictData setValue:currentElementValue forKey:elementName];
}
else if([elementName isEqualToString:@"item"])
{
[arrData addObject:dictData];
}
currentElementValue = @"";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text=[[arrData objectAtIndex:indexPath.row] valueForKey:@"title"];
cell.detailTextLabel.text=[[arrData objectAtIndex:indexPath.row] valueForKey:@"description"];
return cell;
}
#5
1
There is another method for xml parsing using KMLReader. You got dictionary directly from it. you have to import these file and call dictionary For XMLData method from KMLReader file and you get parse dictionary directly from it.just import this class
还有一种使用KMLReader进行xml解析的方法。你直接从它那里得到了字典。您必须从KMLReader文件导入这些文件并调用XMLData方法的dictionary,并直接从该文件获取解析字典。进口这类
KMLReader.h
KMLReader.h
#import <Foundation/Foundation.h>
@interface KMLReader : NSObject <NSXMLParserDelegate>
{
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError **errorPointer;
}
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;
@end
@interface NSDictionary (XMLReaderNavigation)
- (id)retrieveForPath:(NSString *)navPath;
@end
KMLReader.m
KMLReader.m
#import "KMLReader.h"
NSString *const kKMLReaderTextNodeKey = @"text";
@interface KMLReader (Internal)
- (id)initWithError:(NSError **)error;
- (NSDictionary *)objectWithData:(NSData *)data;
@end
@implementation NSDictionary (KMLReaderNavigation)
- (id)retrieveForPath:(NSString *)navPath
{
// Split path on dots
NSArray *pathItems = [navPath componentsSeparatedByString:@"."];
// Enumerate through array
NSEnumerator *e = [pathItems objectEnumerator];
NSString *path;
// Set first branch from self
id branch = [self objectForKey:[e nextObject]];
int count = 1;
while ((path = [e nextObject]))
{
NSLog(@"%@",path);
// Check if this branch is an NSArray
if([branch isKindOfClass:[NSArray class]])
{
if ([path isEqualToString:@"last"])
{
branch = [branch lastObject];
}
else
{
if ([branch count] > [path intValue])
{
branch = [branch objectAtIndex:[path intValue]];
}
else
{
branch = nil;
}
}
}
else
{
// branch is assumed to be an NSDictionary
branch = [branch objectForKey:path];
}
count++;
}
return branch;
}
@end
@implementation KMLReader
#pragma mark -
#pragma mark Public methods
+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer
{
NSLog(@"path :: %@",path);
//NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"xml"];
if ([path length]!=0) {
NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"kml"];
NSLog(@"full path :: %@",fullpath);
NSData *data = [[NSFileManager defaultManager] contentsAtPath:fullpath];
NSDictionary *rootDictionary = [KMLReader dictionaryForXMLData:data error:errorPointer];
NSLog(@"rootDictionary == %@",rootDictionary.description);
return rootDictionary;
}
else
{
return nil;
}
}
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
{
KMLReader *reader = [[KMLReader alloc] initWithError:error];
// NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza&zip=94306&results=1&output=xml"]];
NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.ibtimes.com/rss/articles/reporters/david-zielenziger.rss"]];
NSDictionary *rootDictionary = [reader objectWithData:data1];
[reader release];
NSLog(@"ROOT DICTIONARY :: %@",rootDictionary.description);
return rootDictionary;
}
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [KMLReader dictionaryForXMLData:data error:error];
}
#pragma mark -
#pragma mark Parsing
- (id)initWithError:(NSError **)error
{
if ((self = [super init]))
{
errorPointer = error;
}
return self;
}
- (void)dealloc
{
[dictionaryStack release];
[textInProgress release];
[super dealloc];
}
- (NSDictionary *)objectWithData:(NSData *)data
{
// Clear out any old data
[dictionaryStack release];
[textInProgress release];
dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];
// Initialize the stack with a fresh dictionary
[dictionaryStack addObject:[NSMutableDictionary dictionary]];
// Parse the XML
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
BOOL success = [parser parse];
[parser release];
// Return the stack's root dictionary on success
if (success)
{
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
return resultDict;
}
return nil;
}
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// Get the dictionary for the current level in the stack
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
// Create the child dictionary for the new element
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
// Initialize child dictionary with the attributes, prefixed with '@'
for (NSString *key in attributeDict) {
[childDict setValue:[attributeDict objectForKey:key]
forKey:[NSString stringWithFormat:@"@%@", key]];
}
// If there's already an item for this key, it means we need to create an array
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
NSMutableArray *array = nil;
if ([existingValue isKindOfClass:[NSMutableArray class]])
{
// The array exists, so use it
array = (NSMutableArray *) existingValue;
}
else
{
// Create an array if it doesn't exist
array = [NSMutableArray array];
[array addObject:existingValue];
// Replace the child dictionary with an array of children dictionaries
[parentDict setObject:array forKey:elementName];
}
// Add the new child dictionary to the array
[array addObject:childDict];
}
else
{
// No existing value, so update the dictionary
[parentDict setObject:childDict forKey:elementName];
}
// Update the stack
[dictionaryStack addObject:childDict];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// Update the parent dict with text info
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
// Pop the current dict
[dictionaryStack removeLastObject];
// Set the text property
if ([textInProgress length] > 0)
{
if ([dictInProgress count] > 0)
{
[dictInProgress setObject:textInProgress forKey:kKMLReaderTextNodeKey];
}
else
{
// Given that there will only ever be a single value in this dictionary, let's replace the dictionary with a simple string.
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
id parentObject = [parentDict objectForKey:elementName];
// Parent is an Array
if ([parentObject isKindOfClass:[NSArray class]])
{
[parentObject removeLastObject];
[parentObject addObject:textInProgress];
}
// Parent is a Dictionary
else
{
[parentDict removeObjectForKey:elementName];
[parentDict setObject:textInProgress forKey:elementName];
}
}
// Reset the text
[textInProgress release];
textInProgress = [[NSMutableString alloc] init];
}
// If there was no value for the tag, and no attribute, then remove it from the dictionary.
else if ([dictInProgress count] == 0)
{
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
[parentDict removeObjectForKey:elementName];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Build the text value
[textInProgress appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
// Set the error pointer to the parser's error object
if (errorPointer)
*errorPointer = parseError;
}
@end