Pull to refresh

iPhone парсим XML по человечески

Reading time3 min
Views7.2K
Надоело бороться с NSXMLParser, решил написать свой класс, который используя его возвращает данные в виде NSMutableDictionary, в приятном для человека виде. Соответственно кто желает может его доработать под себя.


Результатом работы парсера будет NSMutableDictionary следующего вида:
Dictionary:
key: "parentNode" value: (NSMutableDictionary*) // родительская нода
key: "name" value: (NSString*) // имя ноды
key: "attributes" value: (NSDictionary*) // атрибуты
key: "childs" value: (NSMutableArray*) // подчиненные ноды каждая нода в виде NSMutableDictionary
key: "content" value: (NSString*) // содержимое ноды CDDATA


Использовать можно следующим образом:
XMLParser * myParser = [[XMLParser alloc]init];
[myParser setDelegate(self)];

if (![myParser parseUrl:@"http://....xml")
{
  NSLog(@"Some error");
}

Для того, чтобы получить результат парсинга используем метод:

-(void)parseFinished:(id) parser result:(NSMutableDictionary*) rootNode
{
  ...
}


* This source code was highlighted with Source Code Highlighter.


Итак, код следующий:

«XMLParser.h»
#import <Foundation/Foundation.h>
#import "XMLParserProtocol.h"

@interface XMLParser : NSObject {
  
  NSMutableDictionary * currentNode;
  id<XMLParserProtocol> delegate;

}

@property (assign) id<XMLParserProtocol> delegate;

-(BOOL) parseUrl:(NSString*)urlToParse;

@end


* This source code was highlighted with Source Code Highlighter.


«XMLParser.m»
#import "XMLParser.h"

@implementation XMLParser

@synthesize delegate;

-(BOOL)parseUrl:(NSString *)urlToParse
{
  
  /**
   Создаем рутовую ноду
   **/
  
  currentNode = [[NSMutableDictionary alloc] init];
  
  [currentNode setObject:@"RootNode" forKey:@"name"];
  [currentNode setObject:[[NSMutableArray alloc]init] forKey:@"childs"];
  
  /**
   Стартуем парсер
   **/
  NSURL * url = [[NSURL alloc] initWithString:urlToParse];
  
  NSXMLParser * parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
  
  [parser setDelegate:self];
  
  
  return [parser parse];
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
  NSMutableDictionary * newNode = [[NSMutableDictionary alloc] init];
  
  [newNode setObject: currentNode forKey:@"parentNode"];
  [newNode setObject: [elementName copy] forKey:@"name"];
  [newNode setObject: [attributeDict copy] forKey:@"attributes"];
  [newNode setObject: [[NSMutableArray alloc]init] forKey:@"childs"];
  
  NSMutableArray * childs = [currentNode objectForKey:@"childs"];
  
  [childs addObject:newNode];
  
  currentNode = newNode;
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
  [currentNode setObject:[string copy] forKey:@"content"];
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{  
  currentNode = [currentNode objectForKey:@"parentNode"];  
}

-(void)parserDidEndDocument:(NSXMLParser *)parser
{
  if (delegate)
  {
    [delegate parseFinished:self result: currentNode];
  }
}

@end


* This source code was highlighted with Source Code Highlighter.



«XMLParserProtocol.h»
#import <UIKit/UIKit.h>
#import "XMLParser.h"

@protocol XMLParserProtocol

@optional

-(void) parseFinished:(id) parser result:(NSMutableDictionary *) rootNode;

@end


* This source code was highlighted with Source Code Highlighter.
Tags:
Hubs:
Total votes 19: ↑14 and ↓5+9
Comments5

Articles