iPhone xml解串器

时间:2011-10-19 15:16:13

标签: iphone xml-parsing xml-deserialization

我是编程新手,这是我的第一个项目,所以我对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 个答案:

答案 0 :(得分:1)

这是一个实现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的“book”,每个标记都有键,而该标记之间的文本作为键的值。这就是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