本篇文章,主要整合一下网上的GdataXML的使用方法以及介绍下nodesForXPath方法。
之前做一个插件开发的时候用到了这个第三方,当时百度使用方法的时候,发现很多都简单介绍了一些基本方法,对于一个比较复杂的XML的时候,使用nodesForXPath 方法比较便捷,而网上介绍这部分的比较少。
过了一两个月,才开始写这篇文章,很多东西竟然都已经记不清了,。当时懒,一直拖,以后还是要及时记录一下,为自己以后翻看,也希望可以帮到别人。
好了,正式开始本篇文章。
GDataXML下载地址:https://github.com/graetzer/GDataXML-HTML
1.导入Pod文件下Classs下的两个文件:
2.拖个简单的xml文件把,原来当时用的复杂的xml 找不到了。
3.修改项目配置
添加libxml2.tbd
添加Header Search Paths中的选项,增加/usr/include/libxml2
添加-fno-objc-arc
OK,至此可以编译运行。
4.方法介绍
在viewcontroller.m中 加个touchesBegan的方法,里面写上测试代码。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//获取track.xml路径
NSString *trackPath = [[NSBundle mainBundle] pathForResource:@"track" ofType:@"xml"];
//通过string创建GDataXMLDocument对象
NSString *trackStr = [[NSString alloc] initWithContentsOfFile:trackPath encoding:NSUTF8StringEncoding error:nil];
GDataXMLDocument *trackDoc = [[GDataXMLDocument alloc] initWithXMLString:trackStr encoding:NSUTF8StringEncoding error:nil];
//1.获取根节点 track
GDataXMLElement *rootElement = [trackDoc rootElement];
// NSLog(@"rootElement attributes:%@,children:%@",rootElement.attributes,rootElement.children);
NSLog(@"rootElemnet first attribute name:%@,stringValue:%@",[rootElement.attributes.firstObject name],[rootElement.attributes.firstObject stringValue]);
}
上面代码的意思可以在xml中表现:
touchesBegan中添加下面的代码,可以获取到track根节点下面所有的signoff节点
//4.获取根节点下的signoff节点数组
NSArray *signOffs = [rootElement elementsForName:@"signoff"];
//5.打印signoff节点的id
for (GDataXMLElement *signOff in signOffs) {
NSLog(@"%@",[signOff.attributes.lastObject stringValue]);
}
至此,GDataXML的基本方法都在了。总结下来就是:
1.获取父节点:通过GDataXMLDocument的rootElement方法和GDataXMLElement的elementsForName方法
2.获取节点的属性的name和value:通过GDataXMLNode的name和stringValue方法(GDataXMLNode就是节点的attribute的类型)
通过这两个步骤,循环使用就可以获取到xml文件中想要的值。
但是,如果xml中嵌套太多,用以上的方法就比较繁琐,而xPath解决了这个问题
5.xPath直接获取想要的节点
//6. xPath获取所有signoff节点
NSString *xpath = [NSString stringWithFormat:@"//%@",@"signoff"];
//track.xml中的signoff节点
NSError *error;
NSArray *xArray = [trackDoc nodesForXPath:xpath error:&error];
if (!error) {
NSLog(@"signoffs:%@",xArray);
}else{
NSLog(@"error:%@",error.localizedDescription);
}
//7.xPath获取含有某个属性的所有signoff节点,比如含有id字段
NSString *xpath2 = [NSString stringWithFormat:@"//%@[@%@]",@"signoff",@"id"];
//track.xml中的signoff节点
NSError *error2;
NSArray *xArray2 = [trackDoc nodesForXPath:xpath2 error:&error2];
if (!error2) {
NSLog(@"含有id的signoffs:%@",xArray2);
}else{
NSLog(@"error:%@",error2.localizedDescription);
}
//8.xPath获取某个属性为特定值的节点,比如id为signoff_2 的节点
NSString *xpath3 = [NSString stringWithFormat:@"//%@[@%@='%@']",@"signoff",@"id",@"signOff_2"];
//track.xml中的signoff节点
NSError *error3;
NSArray *xArray3 = [trackDoc nodesForXPath:xpath3 error:&error3];
if (!error3) {
NSLog(@"signOff_2节点:%@",xArray3);
}else{
NSLog(@"error:%@",error3.localizedDescription);
}
//9.xPath获取id为signOff_2的节点下的userType为MECH的节点
NSString *xpath4 = [NSString stringWithFormat:@"//%@[@%@='%@']/%@[@%@='%@']",@"signoff",@"id",@"signOff_2",@"final",@"userType",@"MECH"];
//track.xml中的signoff节点
NSError *error4;
NSArray *xArray4 = [trackDoc nodesForXPath:xpath4 error:&error4];
if (!error4) {
NSLog(@"MECH的final节点:%@",xArray4);
}else{
NSLog(@"error:%@",error4.localizedDescription);
}
6.直接获取某个节点
6.1 直接获取所有final节点
NSString *xpath5 = [NSString stringWithFormat:@"//%@",@"final"];
NSError *error5;
NSArray *xArray5 = [trackDoc nodesForXPath:xpath5 error:&error5];
NSLog(@"%@",xArray5);
6.2 直接获取属性含有userType的节点
NSString *xpath5 = [NSString stringWithFormat:@"//@%@",@"userType"];
NSError *error5;
NSArray *xArray5 = [trackDoc nodesForXPath:xpath5 error:&error5];
NSLog(@"%@",xArray5);
6.3 获取所有含有字段userType并且值为MECH的final节点
NSString *xpath5 = [NSString stringWithFormat:@"//%@[@%@='%@']",@"final",@"userType",@"MECH"];
NSError *error5;
NSArray *xArray5 = [trackDoc nodesForXPath:xpath5 error:&error5];
NSLog(@"%@",xArray5);
总结xPath
1.//代表遍历所有节点
2.//signoff 代表所有signoff节点
3.//signoff[@id] 代表所有含有id字段的signoff节点 (可以删除track.xml中的一些节点的id看下效果)
4.//signoff[@id='signOff_2'] 代表所有 id 字段为 signOff_2 的signoff节点
5.//signoff[@id='signOff_2']/final[@userType='MECH']代表 id 字段为 signOff_2 的signoff节点 中的userType为MECH的final节点
6.//其他节点,直接可以获取所有的这个‘其他’节点
7.//@属性字段,直接可以获取含有这个‘属性字段’的所有节点
(关于6,7是后来加的,我以前一直以为//代表根节点)