zoukankan      html  css  js  c++  java
  • 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。

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

  • 相关阅读:
    如何在iTerm2中配置oh my zsh?
    sublime中格式化jsx文件
    ES6 new syntax of Literal
    ES6 new syntax of Rest and Spread Operators
    How to preview html file in our browser at sublime text?
    ES6 new syntax of Default Function Parameters
    ES6 new syntax of Arrow Function
    七牛云2018春招笔试题
    Spring-使用注解开发(十二)
    Spring-声明式事物(十一)
  • 原文地址:https://www.cnblogs.com/yjh4866/p/6253879.html
Copyright © 2011-2022 走看看