• 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。

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

  • 相关阅读:
    使用C#实现WinForm窗体的动画效果
    c#制作飘动动画窗体
    c#制作简单启动画面
    C# windows media player详细用法(最全面)
    listbox的索引问题
    WindowsMediaPlayer播放完毕可以播放下一个
    Adobe Photoshop CC 2015安装激活
    C#中OpenFileDialog的使用
    点和多点
    五.几何对象和空间参考
  • 原文地址:https://www.cnblogs.com/yjh4866/p/6253879.html
Copyright © 2020-2023  润新知