десериализатор xml для iPhone - PullRequest
1 голос
/ 19 октября 2011

Я новичок в программировании, и это мой первый проект, так что я не очень разбираюсь в разборе XML и т. Д. Мне нужно проанализировать XML-документ, например ...

<TLMS><TLMSResponse status="SUCCESS">
 <books>
  <book>
   <name>abc</name>
   <author>DEF</author>
   <publisher>HIJ</publisher>
  </book>

  <book>
   <name>xyz</name>
   <author>rus</author>
   <publisher>tuv</publisher>
  </book>
 </books>
</TLMSResponse></TLMS>

Я пыталсямного, но не нашел хорошего десериализатора, который мог бы анализировать этот xml и создавать объекты класса "Book".Любая помощь с благодарностью ...

Спасибо всем

1 Ответ

1 голос
/ 19 октября 2011

Вот пример класса, реализующего протокол NSXMLParserDelegate.

Он будет анализировать этот xml:

<TLMS><TLMSResponse status="SUCCESS">
<books>
<book>
<name>abc</name>
<author>DEF</author>
<publisher>HIJ</publisher>
</book>

<book>
<name>xyz</name>
<author>rus</author>
<publisher>tuv</publisher>
</book>
</books>
</TLMSResponse></TLMS>

в массив словарей, каждый словарь«книга» из xml с ключами для каждого тега и текст между этим тегом в качестве значения для ключа.Вот как выглядит returnData в [_delegate acceptParsedData:[returnData autorelease] withIdent:ident];:

array = 
(
    {
        name:"abc",
        author:"DEF",
        publisher:"HIJ",
    },
    {
        name:"xyz",
        author:"rus",
        publisher:"tuv",
    },
)

JHXMLParser.h

@protocol JHXMLParserDelegate;

@interface JHXMLParser : NSObject <NSXMLParserDelegate> {
    NSString *ident;

    @private
    id _delegate;
    NSMutableArray *_parsedData;
    NSString *_key;
    NSXMLParser *_dataParser;
    NSString *_previousTag;
    NSString *_currentTag;
    NSMutableString *_elementText;
}

@property (nonatomic, retain) NSString *ident;

- (id)initWithKey:(NSString *)Key andData:(NSData *)data;
// delegate management. The delegate is not retained.
- (id <JHXMLParserDelegate>)delegate;
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate;
- (BOOL)start;

@end

@protocol JHXMLParserDelegate <NSObject>

@optional
- (void)acceptParsedData:(NSMutableArray *)parsedData withIdent:(NSString *)ident;

@end

JHXMLParser.m

#import "JHXMLParser.h"

@implementation JHXMLParser

@synthesize ident;

- (id)init {
    if ((self = [super init])) {
        ident = [[NSString alloc] init];
    }
    return self;
}

- (id)initWithKey:(NSString *)key andData:(NSData *)data {
    if ((self = [self init])) {
        _key = key;
        _elementText = [[NSMutableString alloc] initWithString:@""];
        _dataParser = [[NSXMLParser alloc] initWithData:data];
        _dataParser.delegate = self;
    }
    return self;
}

- (id <JHXMLParserDelegate>)delegate {
    id <JHXMLParserDelegate> d = nil;
    if (_delegate) {
        d = _delegate;
    }
    return d;
}
- (void)setDelegate:(id <JHXMLParserDelegate>)delegate {
    _delegate = delegate;
}

- (BOOL)start {
    return [_dataParser parse];
}

- (void)dealloc {
    [ident release];
    [_dataParser release];
    [_parsedData release];
    [_elementText release];
    [_previousTag release];
    [_currentTag release];
    [super dealloc];
}

#pragma mark - NSXMLParser Delegate

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    _parsedData = [[NSMutableArray alloc] init];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    if (_currentTag) {
        [_currentTag release], _currentTag = nil;
    }
    _currentTag = [[NSString alloc] initWithString:elementName];
    if ([elementName isEqualToString:_key]) {
        NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];
        [_parsedData addObject:tmpDict];
        [tmpDict release];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if ([_previousTag isEqualToString:_currentTag]) {
        [_elementText appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    } else {
        if (_elementText) {
            [_elementText release], _elementText = nil;
        }
        _elementText = [[NSMutableString alloc] initWithString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    }
    if (![_previousTag isEqualToString:_currentTag]) {
        if (_previousTag) {
            [_previousTag release], _previousTag = nil;
        }
        _previousTag = [[NSString alloc] initWithString:_currentTag];
    }
    [pool drain];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if ([_previousTag isEqualToString:elementName]) {
        [[_parsedData lastObject] setObject:_elementText forKey:elementName];
    } else {
        if (_previousTag) {
            [_previousTag release], _previousTag = nil;
        }
        _previousTag = [[NSString alloc] initWithFormat:@""];
    }
    [pool drain];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSMutableArray *returnData = [[NSMutableArray alloc] initWithArray:_parsedData];
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:[returnData autorelease] withIdent:ident];
    } else {
        [returnData release], returnData = nil;
    }
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(@"********** ERROR Parsing (%@) XML Data! - %@ - %@ **********", ident, [parseError localizedDescription], [parseError localizedFailureReason]);
    if ([_delegate respondsToSelector:@selector(acceptParsedData:withIdent:)]) {
        [_delegate acceptParsedData:_parsedData withIdent:ident];
    }
}

@end
...