NSXMLParser Simple Example NSXMLParser Simple Example xml xml

NSXMLParser Simple Example


As part of exploring the NSXMLParser I created the following really simple code.

main.m

int main(int argc, const char * argv[]){    @autoreleasepool {        NSLog(@"Main Started");        NSError *error = nil;        // Load the file and check the result        NSData *data = [NSData dataWithContentsOfFile:@"/Users/Tim/Documents/MusicXml/Small.xml"                                          options:NSDataReadingUncached                                            error:&error];        if(error) {            NSLog(@"Error %@", error);            return 1;        }        // Create a parser and point it at the NSData object containing the file we just loaded        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];        // Create an instance of our parser delegate and assign it to the parser        MyXmlParserDelegate *parserDelegate = [[MyXmlParserDelegate alloc] init];        [parser setDelegate:parserDelegate];        // Invoke the parser and check the result        [parser parse];        error = [parser parserError];        if(error)        {            NSLog(@"Error %@", error);            return 1;        }        // All done        NSLog(@"Main Ended");    }    return 0;}

MyXmlParserDelegate.h

#import <Foundation/Foundation.h>@interface MyXmlParserDelegate : NSObject <NSXMLParserDelegate>@end

MyXmlParserDelegate.m

#import "MyXmlParserDelegate.h"@implementation MyXmlParserDelegate- (void) parserDidStartDocument:(NSXMLParser *)parser {    NSLog(@"parserDidStartDocument");}- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {    NSLog(@"didStartElement --> %@", elementName);}-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {    NSLog(@"foundCharacters --> %@", string);}- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {    NSLog(@"didEndElement   --> %@", elementName);}- (void) parserDidEndDocument:(NSXMLParser *)parser {    NSLog(@"parserDidEndDocument");}@end

I've posted it in the hope that it helps someone else.


Swift 4 Example - Parsing Xib-file.

import Foundationclass XMLTransformer: NSObject {   private let parser: XMLParser   private var stack = [Node]()   private var tree: Node?   init(data: Data) {      parser = XMLParser(data: data)      super.init()      parser.delegate = self   }}extension XMLTransformer {   func transform() throws -> Node? {      parser.parse()      if let e = parser.parserError {         throw e      }      assert(stack.isEmpty)      assert(tree != nil)      return tree   }}extension XMLTransformer: XMLParserDelegate {   func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {      guard let tag = Tag(rawValue: elementName) else {         return      }      let node = Node(tag: tag, attributes: attributeDict, nodes: [])      stack.append(node)   }   func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {      guard let tag = Tag(rawValue: elementName) else {         return      }      let lastElement = stack.removeLast()      assert(lastElement.tag == tag)      if let last = stack.last {         last.nodes += [lastElement]      } else {         tree = lastElement      }   }}extension XMLTransformer {   enum Tag: String {      case document      case objects      case tableViewCell, tableViewCellContentView      case subviews      case mapView      case constraints, constraint      case connections, outlet   }}extension XMLTransformer {   class Node {      let tag: Tag      let attributes: [String : String]      var nodes: [Node]      init(tag: Tag, attributes: [String : String], nodes: [Node] = []) {         self.tag = tag         self.attributes = attributes         self.nodes = nodes      }   }}

Usage:

let data = try xib(named: "MapTableViewCell")let c = XMLTransformer(data: data)let tree = try c.transform() // Here you have parsed XML in a Tree representation.


#import <Cocoa/Cocoa.h>@interface AppDelegate : NSObject <NSApplicationDelegate, NSXMLParserDelegate>@property (nonatomic, strong) NSMutableDictionary *dictXML;@property (nonatomic,strong) NSMutableArray *arrOfUpdateDictsByVersion;@property (nonatomic,strong) NSString *strElementBeingParsed;@property (nonatomic,strong) NSString *strElementFinishedParsing;@end#import "AppDelegate.h"@interface AppDelegate ()@property (weak) IBOutlet NSWindow *window;@end@implementation AppDelegate@synthesize dictXML;@synthesize arrOfUpdateDictsByVersion;@synthesize strElementBeingParsed;@synthesize strElementFinishedParsing;- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {    // Insert code here to initialize your application    [self initializeTheArray];    [self startParsingXML];}-(void)initializeTheArray{    self.dictXML = [[NSMutableDictionary alloc] init];    self.arrOfUpdateDictsByVersion = [[NSMutableArray alloc] init];}-(void)startParsingXML{//    NSXMLParser *xmlparser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://cdn.example.com/databaseupdate.xml"]];    NSXMLParser *xmlparser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL fileURLWithPath:@"/Users/vkrmsinha/Desktop/xmlParse.xml"]];    [xmlparser setDelegate:self];    [xmlparser parse];}- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;{    // initial tag comes in here    self.strElementBeingParsed = elementName;    /*if([elementName isEqualToString:@"Version"]){    }    else if ([elementName isEqualToString:@"Update"]){    }*/}- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;{    if(([string rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location != NSNotFound) && ![self.strElementBeingParsed isEqualToString:@"Update"])        return;    // middle part from between the start and end tags comes here    if ([self.strElementBeingParsed isEqualToString:@"Update"]){        NSMutableDictionary *dictUpdate = [NSMutableDictionary dictionary];        [self.arrOfUpdateDictsByVersion addObject:dictUpdate];    }    else if ([self.strElementBeingParsed isEqualToString:@"UpdateType"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        NSMutableDictionary *dictUpd = [NSMutableDictionary dictionary];        [dictUpd setValue:string forKey:@"UpdateType"];        [dictUpdate setValue:dictUpd forKey:@"update"];    }    else if([self.strElementBeingParsed isEqualToString:@"Version"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        // WARNING: ASK IF NO TWO VERSION WILL BE SAME IN FUTURE        [dictUpdate setValue:string forKey:@"version"];    }    else if ([self.strElementBeingParsed isEqualToString:@"FileName"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];        [dict setValue:string forKey:@"FileName"];    }    else if ([self.strElementBeingParsed isEqualToString:@"Hash"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];        [dict setValue:string forKey:@"Hash"];    }    else if ([self.strElementBeingParsed isEqualToString:@"DownloadURL"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];        [dict setValue:string forKey:@"DownloadURL"];    }    else if ([self.strElementBeingParsed isEqualToString:@"Size"]){        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];        [dict setValue:string forKey:@"Size"];    }}- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;{    // ending of tag comes in here    self.strElementFinishedParsing = elementName;    if([elementName isEqualToString:@"Update"]){        [self.arrOfUpdateDictsByVersion sortUsingDescriptors:[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"self.version" ascending:YES], nil]];        NSLog(@"%@", [self.arrOfUpdateDictsByVersion lastObject]);    }    if([elementName isEqualToString:@"UpdateDetails"]){        NSMutableDictionary *dict = [NSMutableDictionary dictionary];        [dict setValue:[[self.arrOfUpdateDictsByVersion lastObject] objectForKey:@"version"] forKey:@"latestVer"];        [dict setValue:[[self.arrOfUpdateDictsByVersion firstObject] objectForKey:@"version"] forKey:@"oldestVer"];        [dict setValue:self.arrOfUpdateDictsByVersion forKey:@"arrOfUpdsByVer"];        NSLog(@"%@", dict);    }}- (void)applicationWillTerminate:(NSNotification *)aNotification {    // Insert code here to tear down your application}<UpdateDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">   <DatabaseUpdates>    <Update>     <UpdateType>CompleteDatabase</UpdateType>     <Version>1</Version>     <FileName>1completedatabase.zip</FileName>     <Hash>ad94431d2fe4cd60eb3347fadaa45d88</Hash>     <DownloadURL>      http://www.example.com/download/new.xml     </DownloadURL>     <Size>2367008</Size>    </Update></DatabaseUpdates></UpdateDetails>