IOS开发解析XML

系统有提供的XML解析类,NSXMLParser,但是不是很不好用啊,该类只会以协议的方式通知扫描时所遇到的XML元素,而且该XML数据的层次关系也看不出来,刚刚封装了一个XML解析功能,直接可以得到根结点,然后就可以查看子结点了。


NSXMLParser+Cobbler.h

//
//  NSXMLParser+Cobbler.h
//  
//
//  Created by yangjianhong-MAC on 11-12-31.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//  QQ:18222469
//

#import <Foundation/Foundation.h>


#pragma mark -
#pragma mark XMLNode
@interface XMLNode : NSObject {
@private
    
    NSString *_strNodeName;//结点名称
    NSDictionary *_dicAttributes;//结点属性
    NSMutableArray *_arrayChild;//子结点
    NSString *_strNodeValue;//结点值
    NSUInteger _nodeDepth;
    XMLNode *_nodeParent;//父结点
}

@property (nonatomic, copy) NSString *nodeName;
@property (nonatomic, copy) NSDictionary *nodeAttributesDict;
@property (nonatomic, readonly) NSArray *children;
@property (nonatomic, copy) NSString *nodeValue;
@property (nonatomic, readonly) NSUInteger nodeDepth;
@property (nonatomic, assign) XMLNode *nodeParent;

- (void)clear;

@end



#pragma mark -
#pragma mark NSXMLParser Cobbler

@interface NSXMLParser (Cobbler)

+ (XMLNode *)parseToXMLNode:(NSData *)dataXML;

@end


NSXMLParser+Cobbler.m
//
//  NSXMLParser+Cobbler.m
//  
//
//  Created by yangjianhong-MAC on 11-12-31.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//  QQ:18222469
//

#import "NSXMLParser+Cobbler.h"


#pragma mark -
#pragma mark XMLNode

@implementation XMLNode

@synthesize nodeName = _strNodeName, nodeValue = _strNodeValue;
@synthesize nodeAttributesDict = _dicAttributes, nodeDepth = _nodeDepth;

#pragma mark Override

//20120610增加
- (void)dealloc
{
    [_strNodeName release];
    [_dicAttributes release];
    [_strNodeValue release];
    _nodeParent = nil;
    
    [super dealloc];
}

- (NSArray *)children
{
    if (_arrayChild.count > 0) {
        return [NSArray arrayWithArray:_arrayChild];
    }
    else {
        return nil;
    }
}

- (void)setNodeParent:(XMLNode *)nodeParent
{
    _nodeParent = nodeParent;
    //计算本结点的深度
    if (nil == nodeParent) {
        //父结点为nil,当前结点深度为0
        _nodeDepth = 0;
    }
    else {
        //当前结点深度为父结点深度+1
        _nodeDepth = nodeParent.nodeDepth + 1;
    }
    //更新子结点的深度
    if (_arrayChild.count > 0) {
        //遍历子结点
        for (XMLNode *nodeChild in _arrayChild) {
            //通过设置父结点的方式更新子结点深度
            nodeChild.nodeParent = self;
        }
    }
}

- (XMLNode *)nodeParent
{
    return _nodeParent;
}

- (NSString *)description
{
    if (_strNodeName.length == 0) {
        return @"";
    }
    
    NSMutableString *mstrDescription = [NSMutableString string];
    //表示深度的空格字符
    NSMutableString *mstrSpace = [[NSMutableString alloc] init];
    for (int i = 0; i < _nodeDepth; i++) {
        [mstrSpace appendString:@" "];
    }
    [mstrDescription appendString:mstrSpace];
    //结点的名称
    [mstrDescription appendFormat:@"\r\n%@<%@", mstrSpace, _strNodeName];
    //结点的属性
    NSArray *arrayKeys = [_dicAttributes allKeys];
    for (NSString *strKey in arrayKeys) {
        [mstrDescription appendFormat:@" \"%@\"=\"%@\"", strKey, [_dicAttributes objectForKey:strKey]];
    }
    [mstrDescription appendString:@">"];
    //结点的值
    if (_strNodeValue.length > 0) {
        [mstrDescription appendFormat:@"%@", _strNodeValue];
    }
    //子结点部分
    if (_arrayChild.count > 0) {
        //遍历所有子结点
        for (XMLNode *nodeChild in _arrayChild) {
            //子结点描述串
            [mstrDescription appendFormat:@"%@", nodeChild];
        }
        [mstrDescription appendFormat:@"\r\n%@", mstrSpace];
    }
    //结点的结束
    [mstrDescription appendFormat:@"</%@>", _strNodeName];
    [mstrSpace release];
    //
    return mstrDescription;
}

#pragma mark Public

- (void)addChildNode:(XMLNode *)childNode
{
    if (nil == _arrayChild) {
        _arrayChild = [NSMutableArray arrayWithCapacity:5];
    }
    //
    [_arrayChild addObject:childNode];
}

- (void)clear
{
    NSArray *arrayChild = [self children];
    //遍历所有子结点
    for (XMLNode *node in arrayChild) {
        //清空子结点的数据
        [node clear];
    }
    //清空当前结点数据
    _nodeDepth = 0;
    self.nodeName = nil;
    self.nodeValue = nil;
    self.nodeAttributesDict = nil;
    self.nodeParent = nil;
    //清空子结点表
    [_arrayChild removeAllObjects];
}

@end



#pragma mark -
#pragma mark XMLParser interface

@interface XMLParser : NSObject <NSXMLParserDelegate> {
@private
    
    XMLNode *_rootNode;
    XMLNode *_currentNode;
}

- (XMLNode *)parse:(NSData *)dataXML;

@end



#pragma mark -
#pragma mark XMLParser implementation

@implementation XMLParser

- (XMLNode *)parse:(NSData *)dataXML
{
    _rootNode = nil;
    _currentNode = nil;
    //
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataXML]; //设置XML数据
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser setDelegate:self];
    [parser parse];
    [parser release];//20120610增加
    
    return _rootNode;
}

#pragma mark NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"element start:%@",elementName);
    //
    if (nil == _rootNode) {
        //创建根结点
        _rootNode = [[[XMLNode alloc] init] autorelease];
        _rootNode.nodeName = elementName;
        _rootNode.nodeAttributesDict = attributeDict;
        _rootNode.nodeParent = nil;
        //
        _currentNode = _rootNode;
    }
    else {
        //
        XMLNode *nodeChild = [[XMLNode alloc] init];
        nodeChild.nodeName = elementName;
        nodeChild.nodeAttributesDict = attributeDict;
        nodeChild.nodeParent = _currentNode;
        //
        [_currentNode addChildNode:nodeChild];
        _currentNode = nodeChild;
        [nodeChild release];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    //去掉字符串首尾的空字符
    NSString *strValidValue = [string stringByTrimmingCharactersInSet:
                               [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSLog(@"element value:%@",strValidValue);
    _currentNode.nodeValue = strValidValue;
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"element end.");
    //
    _currentNode = _currentNode.nodeParent;
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"parse error:%@", parseError);
    _rootNode = nil;
}

@end



#pragma mark -
#pragma mark NSXMLParser Cobbler

@implementation NSXMLParser (Cobbler)

+ (XMLNode *)parseToXMLNode:(NSData *)dataXML
{
    XMLParser *parser = [[XMLParser alloc] init];
    XMLNode *node = [parser parse:dataXML];
    [parser release];
    return node;
}

@end

为了方便,以及想类名的麻烦,只是给NSXMLParser写了个分类,静态方法,参数为NSData,返回类型为XMLNode。

有什么问题,或者使用不方便的找我哇

posted @ 2012-01-01 19:34  脱离语言  阅读(141)  评论(0编辑  收藏  举报