iOS之数据解析之XML解析详解
程序员文章站
2023-12-20 20:15:34
xml解析常见的两种方式:dom解析和sax解析
dom解析
dom:document object model(文档对象类型).解析xml时,读入整个xm...
xml解析常见的两种方式:dom解析和sax解析
dom解析
- dom:document object model(文档对象类型).解析xml时,读入整个xml文档并构建一个驻留内存的树结构(节点树),通过遍历数结构可以检索任意xml节点,读取它的属性和值,而且通常情况下,可以借助xpath,直接查询xml节点.
- 进行dom方式解析数据需要使用一个第三方的类gdataxmlnode
- gdataxmlnode是google提供的开源xml解析类,对libxml2.tbd进行了objective-c的封装,能对较小或者中等的xml文档进行读写操作且支持xpath语法.
- gdataxmlnode使用方法:
1 获取gdataxmlnode.h/m文件,将gdataxmlnode.h/m文件添加到工程中.
2 向工程中添加'libxml2.tbd'动态库.
3 在工程的”build settings”页中找到”header search path”项,添加”/usr/include/libxml2”.
4 导入”gdataxmlnode.h”文件到头文件中,如工程能编译通过,则说明gdataxmlnode添加成功.
(gdataxmlnode第三方可在github搜索下载)
解析代码如下:
-(void)xmldommethed{ //盛放所有的字典 self.sourcearray = [nsmutablearray array]; //setp1.得到需要解析的数据 nsstring *xmlpath = [[nsbundle mainbundle] pathforresource:@"xmldemo" oftype:@"xml"]; //step2.转换为nsdata类型 nsdata *xmldata = [nsdata datawithcontentsoffile:xmlpath]; //step3.1 构建document文档对象(options预留参数) gdataxmldocument *doc = [[gdataxmldocument alloc] initwithdata:xmldata options:0 error:nil]; //step3.2 找到根节点(students) gdataxmlelement *rootelement = [doc rootelement]; //step3.3 找到根节点的所有子节点 nsarray *allsubnotes = [rootelement elementsforname:@"student"]; //step3.3 找到student节点的所有子节点 for (gdataxmlelement *item in allsubnotes) { //每次循环开始的时候,说明是一个新的student节点,我们需要字典来盛放它所有的值 nsmutabledictionary *studentdic = [nsmutabledictionary dictionary]; //得到name节点 nsarray *namearray = [item elementsforname:@"name"]; gdataxmlelement *nameelement = [namearray objectatindex:0]; nsstring *name = [nameelement stringvalue]; [studentdic setobject:name forkey:@"name"]; //取出age nsarray *agearray = [item elementsforname:@"age"]; gdataxmlelement *ageelement = [agearray objectatindex:0]; nsstring *age = [ageelement stringvalue]; [studentdic setobject:age forkey:@"age"]; //取出sex nsarray *sexarray = [item elementsforname:@"sex"]; gdataxmlelement *sexelement = [sexarray objectatindex:0]; nsstring *sex = [sexelement stringvalue]; [studentdic setobject:sex forkey:@"sex"]; //把student字典添加到数组中 [self.sourcearray addobject:studentdic]; } nslog(@"%@",self.sourcearray); }
写入代码如下:
//通过dom解析方式为xml增加节点 (sax只可以读取,不可以添加) - (void)domaddnote{ //获得文件路径 nsstring *xmlpath = [[nsbundle mainbundle] pathforresource:@"xmldemo" oftype:@"xml"]; //将文件转换为data类型 nsdata *xmldata = [nsdata datawithcontentsoffile:xmlpath]; gdataxmldocument *doc = [[gdataxmldocument alloc] initwithdata:xmldata options:0 error:nil]; gdataxmlelement *rootelement = [doc rootelement]; //创建一个我们需要添加的节点(student) gdataxmlelement *createelement = [gdataxmlelement elementwithname:@"student"]; //为student节点添加属性 [createelement addattribute:[gdataxmlelement attributewithname:@"attribute" stringvalue:@"aa"]]; //为student节点添加子节点 gdataxmlelement *namenode = [gdataxmlelement elementwithname:@"name" stringvalue:@"美丽"]; [createelement addchild:namenode]; gdataxmlelement *agenode = [gdataxmlelement elementwithname:@"age" stringvalue:@"18"]; [createelement addchild:agenode]; gdataxmlelement *sexnode = [gdataxmlelement elementwithname:@"sex" stringvalue:@"男"]; [createelement addchild:sexnode]; //将创建好的student节点,添加到根节点,也就是students节点下 [rootelement addchild:createelement]; //得到所有的student节点 nsarray *stuelementarray = [rootelement elementsforname:@"student"]; //遍历得到每个student节点,以便获得student的子节点的值。 for (gdataxmlelement* item in stuelementarray) { //获得student节点的attribute属性值 nslog(@"%@",[[item attributeforname:@"attribute"] stringvalue]); nsarray *namearray = [item elementsforname:@"name"]; gdataxmlelement *nameelement = [namearray objectatindex:0]; nsstring *name = [nameelement stringvalue]; //取出age nsarray *agearray = [item elementsforname:@"age"]; gdataxmlelement *ageelement = [agearray objectatindex:0]; nsstring *age = [ageelement stringvalue]; //取出sex nsarray *sexarray = [item elementsforname:@"sex"]; gdataxmlelement *sexelement = [sexarray objectatindex:0]; nsstring *sex = [sexelement stringvalue]; nslog(@"name=%@---age=%@----sex=%@",name,age,sex); } }
sax解析
- sax:simple api for xml,基于事件驱动的解析方式,逐行解析数据(采用协议回调机制).
- nsxmlparser
1 nsxmlparser是ios自带的xml解析类,采用sax方式解析数据
2 解析过程由nsxmlparserdelegate协议方法回调
3 解析过程:开始标签->取值->结束标签->取值
//遵循协议 @interface rootviewcontroller ()<nsxmlparserdelegate>
//xml解析之sax解析 -(void)xmlsaxmethod{ //得到需要解析的数据 nsstring *xmlpath = [[nsbundle mainbundle] pathforresource:@"xmldemo" oftype:@"xml"]; nsdata *xmldata = [nsdata datawithcontentsoffile:xmlpath]; //创建sax解析的工具类对象 nsxmlparser *saxparser = [[nsxmlparser alloc] initwithdata:xmldata]; //指定代理 saxparser.delegate = self; //开始解析 sax解析是一个同步的过程 bool isparse = [saxparser parse]; if (isparse) { nslog(@"解析完成"); }else{ nslog(@"解析失败"); } nslog(@"我是在解析结束下面"); }
pragma mark - sax解析的代理方法
//开始解析的代理方法 -(void)parserdidstartdocument:(nsxmlparser *)parser { nslog(@"开始解析"); self.saxarray = [nsmutablearray array]; } //开始解析某个节点 //elementname:标签名称 //namespaceuri:命名空间指向的链接 //qname:命名空间的名称 //attributedict:节点的所有属性 -(void)parser:(nsxmlparser )parser didstartelement:(nsstring )elementname namespaceuri:(nsstring )namespaceuri qualifiedname:(nsstring )qname attributes:(nsdictionary<nsstring *,nsstring *> *)attributedict { nslog(@"开始解析%@节点",elementname); //当开始解析student标签的时候,就应该初始化字典,因为一个字典就对应的是一个学生的信息 if ([elementname isequaltostring:@"student"]) { self.saxdic = [nsmutabledictionary dictionary]; } } //获取节点之间的值 -(void)parser:(nsxmlparser )parser foundcharacters:(nsstring )string { nslog(@"取值--------%@",string); if (self.valuestring) {//说明有值 [self.valuestring appendstring:string]; } else { self.valuestring = [nsmutablestring stringwithstring:string]; } } //某个节点结束取值 -(void)parser:(nsxmlparser )parser didendelement:(nsstring )elementname namespaceuri:(nsstring )namespaceuri qualifiedname:(nsstring )qname { if ([elementname isequaltostring:@"name"]) {//说明name节点已经取值结束 [self.saxdic setobject:self.valuestring forkey:elementname]; } if ([elementname isequaltostring:@"age"]) { [self.saxdic setobject:self.valuestring forkey:elementname]; } if ([elementname isequaltostring:@"sex"]) { [self.saxdic setobject:self.valuestring forkey:elementname]; } if ([elementname isequaltostring:@"student"]) { [self.saxarray addobject:self.saxdic]; } self.valuestring = nil;//置空 nslog(@"结束%@节点的解析",elementname); } //结束解析 -(void)parserdidenddocument:(nsxmlparser *)parser { //可以使用解析完成的数据 nslog(@"%@",self.saxarray); nslog(@"整个解析结束"); } //解析出错 -(void)parser:(nsxmlparser )parser parseerroroccurred:(nserror )parseerror { nslog(@"解析出现错误-------%@",parseerror.description); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。