0

Say if I have the following profiles parsed from an xml file on the web and wanted to remove the duplicates, how would I do that? For example there are 2 profiles with the same first name (Amin) and I only want to display 1. I am displaying all the profiles parsed from the xml file in the command output window using NSLog and say if I wanted to have a button that should filter the profiles and delete the duplicates and update the command output window (using NSLog) with duplicates being removed.

<profiles>
  <profile>
    <firstname>Amin</firstname>
    <lastname>Ziarkash</lastname>
    <address>Melisstokelaan 2068</address>
    <zipcode>2541 GH</zipcode>
    <city>Den Haag</city>
    <email>a.ziarkash@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Niko</firstname>
    <lastname>De Vries</lastname>
    <address>Sterrelaan 34</address>
    <zipcode>3342 JH</zipcode>
    <city>Amsterdam</city>
    <email>niko@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Marcel</firstname>
    <lastname>Janssens</lastname>
    <address>Voorhoeveweg 11</address>
    <zipcode>6006SV</zipcode>
    <city>Weert</city>
    <email>marcel.j@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Amin</firstname>
    <lastname>Ziarkash</lastname>
    <address>Melisstokelaan 2068</address>
    <zipcode>2541 GH</zipcode>
    <city>Den Haag</city>
    <email>a.ziarkash@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Kevin</firstname>
    <lastname>De Vries</lastname>
    <address>Stuyvesantweg 2</address>
    <zipcode>2541 GH</zipcode>
    <city>Wolvega</city>
    <email>kevin@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Niko</firstname>
    <lastname>De Vries</lastname>
    <address>Sterrelaan 34</address>
    <zipcode>3342 JH</zipcode>
    <city>Amsterdam</city>
    <email>niko@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Gido</firstname>
    <lastname>Van der Veen</lastname>
    <address>Klausstraat 12</address>
    <zipcode>7726 GH</zipcode>
    <city>Den Haag</city>
    <email>gido.j@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Nilo</firstname>
    <lastname>Yaqobi</lastname>
    <address>Kamperslaan 15</address>
    <zipcode>3728 JH</zipcode>
    <city>Delft</city>
    <email>nilo@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Casper</firstname>
    <lastname>Van Zanten</lastname>
    <address>Molenweg 98</address>
    <zipcode>3411 HJ</zipcode>
    <city>Amsterdam</city>
    <email>Casper.j@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Geert</firstname>
    <lastname>Diujkstra</lastname>
    <address>Binnenszijde 47</address>
    <zipcode>5362 PL</zipcode>
    <city>Amsterdam</city>
    <email>geert@hotmail.com</email>
  </profile>

  <profile>
    <firstname>Thijs</firstname>
    <lastname>Venema</lastname>
    <address>Koolstraat 21</address>
    <zipcode>6473 AA</zipcode>
    <city>Amsterdam</city>
    <email>venema@hotmail.com</email>
  </profile>

</profiles>

The code for parsing:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

bool isStatus;
ViewController *currentProfile;
ViewController *xmlParser;
NSXMLParser *parser;
NSMutableString *currentNodeContent;

-(id)loadXMLByURL:(NSString *)urlString
{
    profile = [[NSMutableArray alloc] init];
    NSURL *url = [NSURL URLWithString:urlString];
    NSData *data = [[NSData alloc] initWithContentsOfURL:url];
    parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    [parser parse];
    return self;
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"firstname"])
    {
        currentProfile = [ViewController alloc];
        isStatus = YES;
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"firstname"])
    {
        currentProfile->firstName = currentNodeContent;
        NSLog(@"%@",currentProfile->firstName);
        [profile addObject:currentProfile];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    xmlParser = [[ViewController alloc] loadXMLByURL:@"http://dierenpensionlindehof.nl/profiles1.xml"];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

EDIT

I made a separate class for the parsing to ease the process. Now I want to load the -(void)loadXML from this class (XMLParser class) in the original ViewController class's viewDidLoad but it gives me errors.. Can someone tell me what I am doing wrong here?

ViewController.m

#import "ViewController.h"
#import "XMLParser.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self XMLParser:loadXML];

}

XMLParser.h

#import <Foundation/Foundation.h>
#import "ViewController.h"

@interface XMLParser : NSObject

{
    NSMutableArray *profile;
    NSString *firstName;
}

- (void)loadXMLByURL:(NSString *)urlString; //Added after edit
- (void)loadXML; //Added after edit

@end

XMLParser.m

#import "XMLParser.h"

@implementation XMLParser

bool isStatus;
XMLParser1 *currentProfile;
XMLParser1 *xmlParser;
NSXMLParser *parser;
NSMutableString *currentNodeContent;

-(void)loadXMLByURL:(NSString *)urlString
{
    profile = [[NSMutableArray alloc] init];
    NSURL *url = [NSURL URLWithString:urlString];
    NSData *data = [[NSData alloc] initWithContentsOfURL:url];
    parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    [parser parse];
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"firstname"])
    {
        currentProfile = [XMLParser1 alloc];
        isStatus = YES;
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"firstname"])
    {
        currentProfile->firstName = currentNodeContent;
        NSLog(@"%@",currentProfile->firstName);
        [profile addObject:currentProfile];
    }
}

- (void)loadXML
{
    [self loadXMLByURL:@"http://dierenpensionlindehof.nl/profiles1.xml"];
}

@end
azi_santos
  • 105
  • 1
  • 12
  • Why does `loadXMLByURL:` return `self`? Why does `viewDidLoad` create `ViewController`? Very strange. – trojanfoe Dec 30 '13 at 11:32
  • @trojanfoe This is how I got it to work, sorry but I am new to objective-C so don't have much experience yet.. How would you suggest I should do it? It seems to work this way though, it outputs the names as I want them. – azi_santos Dec 30 '13 at 11:40
  • Well it's fine in as much as you have a custom class to perform the parsing of the XML (and presumably store it in some form too), however that isn't a view controller, so call it `XmlParser` (or some such) and derive it from `NSObject`. This can perform the duplicate filtering as well. There is no need to return `self` from `loadXMLByURL:` however, so have that return `BOOL` or `void` if there is no possibility of errors occurring in that method. – trojanfoe Dec 30 '13 at 11:47
  • @trojanfoe Thanks for your answer, I changed the loadXMLByURL 'code' to void and in viewDidLoad 'code'. I call it by [self loadXMLByURL:@"..."]; 'code'. I don't get what you mean by: so call it XmlParser (or some such) and derive it from NSObject. Can you explain a bit more please? For the reduplication proces.. – azi_santos Dec 30 '13 at 12:00
  • It looks like you have a class called `ViewController` in which you create another instance when the view loads. This is wrong. Create another XML parser class instead and put all functionality related to loading and filter the XML data in that class. – trojanfoe Dec 30 '13 at 12:13
  • @trojanfoe So I made another class, called it XMLParser and put the code in the .h and .m file.. Now when I want to load that class in the viewDidLoad of the ViewCotroller class it gives me an error: XMLParser loadXMLByURL]; it says no known class method for selector 'loadXMLByURL' – azi_santos Dec 30 '13 at 12:36
  • Edit your question and post the new code. – trojanfoe Dec 30 '13 at 14:08
  • @trojanfoe I edited the code.. Can you see what I am doing wrong here? – azi_santos Dec 30 '13 at 14:27
  • Yes, the `XMLParser` class doesn't contain the method `loadXMLByURL:`. Move all related methods and instance variables into that class. – trojanfoe Dec 30 '13 at 15:37
  • @trojanfoe Thanks for your help, I managed to fix it by: XMLParser* parser = [[XMLParser alloc]init]; [parser loadXML]; Now the actual problem was to reduplicate the profiles.. How could I do that? – azi_santos Dec 30 '13 at 22:51

0 Answers0