在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
当前Objective-C可用的XML解析器比较多(可以到我的文章《介绍两种常用的XML解析方式(NSXMLParser & GDataXMLNode)》和《如何选择你的iPhone XML解析器》中了解)。想了解DOM相关知识可参看W3School。 其实Google的GDataXMLNode 其实也是一种基于DOM结构的XML解析器,GDataXMLNode只是是对libxml XML解析库进行了Objective-C的封装。在大多是情况下GDataXMLNode完全可以满足我们解析XML格式文件的需求,也能够对文档XML文件结构进行修改(可能需要自己实现一些东西)。但是GDataXMLNode存在一个问题,就是GDataXMLNode中的每一个Node节点对象对应一个libxml中的xmlNodePtr的结构体,但这种关系并不是一一对应的,也就是你不能通过xmlNodePtr的结构体对应到响应的Node对象,GDataXMLNode中你可以发现每次取相同位子的一个节点,都是对应不同的Node对象,虽然这些Node对象内容是相同的。以为GDataXMLNode中每次都是通过xmlNodePtr去创建一个新的Node对象,这对于只关注文档内容的解析是没有影响的,但是如果涉及到大量节点的操作、遍历,可能会有些麻烦。 之前我也做过一些改造工作,希望让GDataXMLNode实现一种Node对象与xmlNodePtr结构体一一对应的方法,尝试过通过字典Dictionary映射表,将xmlNodePtr结构体的地址作为key值,对应一个Node对象,在每次要找到一个对象时,先查找字典里是否已经存在xmlNodePtr对应的Node。这种方式也存在问题,如每次对Node节点进行操作(增、删、改等)时,都得更新一下映射表,同时映射表因为存在每个Node对象的一份拷贝,占用额外的内存。(如果各位大牛有更好的方法能够将C里面的结构体与对象语言中的对象一一对应,可以分享一下) 因此我就开始着手自己开发XML解析器了,libxml不能用了,只能从NSXMLParser找方法了,NSXMLParser本身是基于SAX方式的解析,因此DOM树需要自己去创建,具体实现细节可直接看我的源码ESXML (欢迎大家到我的Github(github.com/tracy-e))。下面贴出ESXML的头文件:
ESXMLNode.h// // ESXMLNode.h // ESXML // // Created by Tracy E on 12-9-8. // Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved. // #import <Foundation/Foundation.h> enum { ES_ELEMENT_NODE = 1, ES_ATTRIBUTE_NODE = 2, ES_TEXT_NODE = 3, ES_COMMENT_NODE = 8, ES_DOCUMENT_NODE = 9, }; @class ESXMLDocument; @interface ESXMLNode : NSObject{ NSMutableDictionary *_attributes; NSMutableArray *_childNodes; } @property (readonly, copy) NSString *nodeName; @property (nonatomic, copy) NSString *nodeValue; @property (readonly) unsigned short nodeType; @property (nonatomic, assign) ESXMLDocument *ownerDocument; @property (nonatomic, assign) ESXMLNode *parentNode; @property (nonatomic, assign) ESXMLNode *firstChild; @property (nonatomic, assign) ESXMLNode *lastChild; @property (nonatomic, assign) ESXMLNode *previousSibling; @property (nonatomic, assign) ESXMLNode *nextSibling; @property (nonatomic, retain) NSMutableArray *childNodes; @property (nonatomic, retain) NSMutableDictionary *attributes; - (ESXMLNode *)insertBefore:(ESXMLNode *)newChild refChild:(ESXMLNode *)refChild; - (ESXMLNode *)replaceChild:(ESXMLNode *)newChild oldChild:(ESXMLNode *)oldChild; - (ESXMLNode *)removeChild:(ESXMLNode *)oldChild; - (ESXMLNode *)appendChild:(ESXMLNode *)newChild; - (BOOL)hasChildNodes; - (ESXMLNode *)cloneNode:(BOOL)deep; - (BOOL)isSameNode:(ESXMLNode *)other; - (BOOL)isEqualNode:(ESXMLNode *)other; - (void)visitTree; @end
ESXMLDocument.h// // ESXMLDoument.h // ESXML // // Created by Tracy E on 12-9-8. // Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved. // #import "ESXMLNode.h" @class ESXMLElement; @class ESXMLText; @interface ESXMLDocument : ESXMLNode<NSXMLParserDelegate>{ @private ESXMLElement *_topElement; ESXMLNode *_lastNode; NSMutableString *_chars; NSMutableArray *_stack; } @property (nonatomic, retain) ESXMLElement *documentElement; @property (nonatomic, copy) NSString *URL; @property (nonatomic, copy) NSString *title; @property (nonatomic, readonly) ESXMLElement *head; @property (nonatomic, readonly) ESXMLElement *body; @property (nonatomic, retain) NSMutableArray *styleSheets; - (id)initWithXMLString:(NSString *)string baseURL:(NSString *)url; - (ESXMLElement *)createElement:(NSString *)tagName; - (ESXMLText *)createTextNode:(NSString *)text; - (ESXMLElement *)getElementById:(NSString *)elementId; - (NSArray *)getElementsByTagName:(NSString *)tagName; @end
ESXMLElement.h// // ESXMLElement.h // ESXML // // Created by Tracy E on 12-9-8. // Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved. // #import "ESXMLNode.h" @interface ESXMLElement : ESXMLNode @property (nonatomic, retain) NSString *tagName; - (id)initWithName:(NSString *)tagName attributes:(NSDictionary *)attributes; - (NSString *)innerText; - (void)setInnerText:(NSString *)text; - (NSString *)innerHTML; - (void)setInnerHTML:(NSString *)html; - (ESXMLElement *)getElementById:(NSString *)elementId; - (NSArray *)getElementsByTagName:(NSString *)tagName; - (NSString *)getAttribute:(NSString *)attributeName; - (void)setAttribute:(NSString *)attributeName value:(NSString *)attributeValue; - (void)removeAttribute:(NSString *)attributeName; @end
ESXMLText.h// // ESXMLText.h // ESXML // // Created by Tracy E on 12-9-8. // Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved. // #import "ESXMLNode.h" @interface ESXMLText : ESXMLNode @property (nonatomic, readonly) unsigned length; @property (nonatomic, copy) NSString *wholeText; - (id)initWithText:(NSString *)text; @end
|
请发表评论