NSXMLParser: при разборе XML-файла отображаются два идентичных массива - PullRequest
2 голосов
/ 14 июля 2011

Может быть, кто-то может помочь ...

У меня проблема с тем, что при разборе файла XML у нас есть два массива. Такова конструкция ДВУХ одинаковых возвращаемых массивов:

xmlcont = [[XMLController alloc] loadXMLByURL:@"http://link_to_XML_file.xml"];

У меня есть следующие файлы:

Constants.h

#import <Foundation/Foundation.h>

extern NSString * const ITEM;
extern NSString * const TITLE;
extern NSString * const IMAGE;
extern NSString * const DESCRIPTION;
extern NSString * const TEXT;

@interface Constants : NSObject
{

}

@end

Constants.m

#import "Constants.h"

@implementation Constants

NSString * const ITEM           = @"item";
NSString * const TITLE          = @"title";
NSString * const IMAGE          = @"image";
NSString * const DESCRIPTION    = @"description";
NSString * const TEXT           = @"text";

 - (void)dealloc
{
    [super dealloc];
}

@end

myNews.h

#import <Foundation/Foundation.h>

@interface myNews : NSObject
{
    NSString *itemTitle;
    NSString *itemImageUrl;
    NSString *itemDescription;
    NSString *itemText;
}

@property (nonatomic, retain) NSString *itemTitle;
@property (nonatomic, retain) NSString *itemImageUrl;
@property (nonatomic, retain) NSString *itemDescription;
@property (nonatomic, retain) NSString *itemText;

@end

myNews.m

#import "myNews.h"

@implementation myNews

@synthesize itemTitle;
@synthesize itemImageUrl;
@synthesize itemDescription;
@synthesize itemText;

@end

XMLController.h

#import <Foundation/Foundation.h>

@class Constants;
@class myNews;

@interface XMLController : NSObject
{
    NSMutableString *currentNodeContent;
    NSMutableArray *newsArray;
    NSXMLParser *parser;
    myNews *currentNew;
}

@property (readonly, retain) NSMutableArray *newsArray;

-(id)loadXMLByURL:(NSString *)urlString;

@end

XMLController.m

#import "XMLController.h"
#import "Constants.h"
#import "myNews.h"

@implementation XMLController

@synthesize newsArray;

-(id)loadXMLByURL:(NSString *)urlString
{
    newsArray = [[NSMutableArray alloc] init];
    NSURL *url = [NSURL URLWithString: urlString];
    parser = [[NSXMLParser alloc] initWithContentsOfURL: url];
    [parser setDelegate:(id)self];
    [parser parse];
    return self;
}

-(void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString: ITEM])
    {
        currentNew = [myNews alloc];
        currentNodeContent = [[NSMutableArray alloc] init];
    }
}

-(void) parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{    
    if ([elementName isEqualToString: TITLE])
    {
        currentNew.itemTitle = currentNodeContent;
    }

    if ([elementName isEqualToString: IMAGE])
    {
        currentNew.itemImageUrl = currentNodeContent;
    }

    if ([elementName isEqualToString: DESCRIPTION])
    {
        currentNew.itemDescription = currentNodeContent;
    }

    if ([elementName isEqualToString: TEXT])
    {
        currentNew.itemText = currentNodeContent;
    }

    if ([elementName isEqualToString: ITEM])
    {
        [newsArray addObject:currentNew];
        [currentNew release];
        currentNew = nil;
        [currentNodeContent release];
        currentNodeContent = nil;
    }
}

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

@end

myAppDelegate.h

#import <UIKit/UIKit.h>
#import "MainViewController.h"
#import "DetailViewController.h"

@class MainViewController;
@class DetailViewController;

@interface myAppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow *window;
    UINavigationController *myNavigationController;    
    MainViewController *myMainViewController;
    DetailViewController *myDetailViewController;  
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *myNavigationController;
@property (nonatomic, retain) IBOutlet MainViewController *myMainViewController;
@property (nonatomic, retain) IBOutlet DetailViewController *myDetailViewController;

@end

myAppDelegate.m

#import "myAppDelegate.h"
#import "myNews.h"
#import "MainViewController.h"
#import "DetailViewController.h"

@implementation myAppDelegate

@synthesize window;
@synthesize myNavigationController;
@synthesize myMainViewController;
@synthesize myDetailViewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [window addSubview:myNavigationController.view];
    [window makeKeyAndVisible];

    return YES;
}

- (void)dealloc 
{
    [window release];
    [myNavigationController release];
    [myMainViewController release];
    [myDetailViewController release];
    [super dealloc];
}

@end

MainViewController.h

#import <UIKit/UIKit.h>
#import "XMLController.h"

@interface MainViewController : UIViewController
{
    XMLController *xmlcont;
}

@end

MainViewController.m

#import "MainViewController.h"
#import "myNews.h"

@implementation MainViewController

- (void)viewDidLoad
{    
    [super viewDidLoad];

    xmlcont = [[XMLController alloc] loadXMLByURL:@"http://link_to_XML_file.xml"];

    NSLog(@"array = %@", [xmlcont newsArray]);

    for (myNews *oneNew in [xmlcont newsArray]) {

        NSLog(@"URL = %@", [oneNew itemImageUrl]);

    }

}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)dealloc 
{
    [super dealloc];
}

@end

XML-файл:

<?xml version="1.0" encoding="UTF-8"?> 
<channel>
    <item>
        <title>news 1</title>
        <image>http://link_to_JPG_file_1.jpg</image>
        <description>description 1</description>
        <text>text 1</text>
    </item>
    <item>
        <title>news 2</title>
        <image>http://link_to_JPG_file_2.jpg</image>
        <description>description 2</description>
        <text>text 2</text>
    </item>
</channel>

В результате реализации вывода я вижу:

2011-07-14 13:18:27.785 my[18673:207] array = (
    "<myNews: 0x4e28dc0>",
    "<myNews: 0x4e29080>"
)
2011-07-14 13:18:27.787 my[18673:207] URL = http://link_to_JPG_file_1.jpg
2011-07-14 13:18:27.818 my[18673:207] URL = http://link_to_JPG_file_2.jpg

2011-07-14 13:18:27.959 my[18673:207] array = (
    "<myNews: 0x4b5a010>",
    "<myNews: 0x4b5a310>"
)
2011-07-14 13:18:27.960 my[18673:207] URL = http://link_to_JPG_file_1.jpg
2011-07-14 13:18:27.963 my[18673:207] URL = http://link_to_JPG_file_2.jpg

MainWindow.xib

Снимок экрана MainWindow.xib

Скажите, пожалуйста, где я могу ошибаться?

1 Ответ

0 голосов
/ 14 июля 2011

Вы получаете дважды вызываемый viewDidLoad (что не обязательно является ошибкой).Вам просто нужно добавить некоторую логику, чтобы загружать ваш XML только один раз.

- (void)viewDidLoad
{    
    [super viewDidLoad];

    if (nil == xmlcont) {
        xmlcont = [[XMLController alloc] loadXMLByURL:@"http://link_to_XML_file.xml"];
        NSLog(@"array = %@", [xmlcont newsArray]);

        for (myNews *oneNew in [xmlcont newsArray]) {
            NSLog(@"URL = %@", [oneNew itemImageUrl]);
        }
    }
}

PS Если вы добавите этот код и по-прежнему получите выходные данные дважды, вы создадите две версии ViewController.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...