libxml使用小结

前言:做IOS开发,大家应该用到TouchXML这个每三方类库,其实它解析xml的根本还是用到了libxml来解析,
libxml是用C语言写的,只不过TouchXML把libxml封装成了OC,方便我们调用。大家理解了下面libxml的一些简单操作,
那对于大家理解TouchXML更有作用,会是对编程的一个提升

1
// 2 // ViewController.m 3 // drawertest 4 // 5 // Created by vincent_guo on 13-5-8. 6 // 7 // 8 9 #import "ViewController.h" 10 #import "NSString+Kwok.h" 11 12 #include <libxml/tree.h> 13 #include <libxml/xmlreader.h> 14 #include <libxml/parser.h> 15 #include <libxml/xpath.h> 16 17 18 @property(nonatomic,retain)NSMutableArray *computers; 19 @end 20 21 @implementation ViewController 22 23 - (void)viewDidLoad 24 { 25 [super viewDidLoad]; 26 self.computers = [NSMutableArray array]; 27 [self.computers addObject:@"MacBook Pro"]; 28 [self.computers addObject:@"Lenovo E40"]; 29 } 30 31 //这里本人创建一个xml文件的内容,方便大家参照着解读代码 32 //<?xml version="1.0" encoding="UTF-8"?> 33 //<vincent> 34 // <computers count="2"> 35 // <computer>MacBook Pro</computer> 36 // <computer>Lenovo E40</computer> 37 // </computers> 38 // <telephone>Sony Ericsson索爱</telephone> 39 //</vincent> 40 41 //创建一个xml 42 -(void)libxmlCreate{ 43 //xml文件路径 本人放在ios沙盒的Document目录下 44 NSString *xmlFilePath = [@"text.xml" appendFileNameBehindDocument]; 45 46 xmlDocPtr xmlDoc = xmlNewDoc(BAD_CAST("1.0"));//xml的版本1.0 47 xmlNodePtr rootEle = xmlNewNode(NULL, BAD_CAST("vincent"));//创建根节点 48 xmlDocSetRootElement(xmlDoc, rootEle);//将rootEle节点加在xml的根节点 49 50 //New一个节点 51 xmlNodePtr computersEle = xmlNewNode(NULL, BAD_CAST("computers")); 52 //往computers节点添加属性 53 xmlNewProp(computersEle, BAD_CAST("count"), BAD_CAST("2")); 54 //添加computers节点到根节点下 55 xmlAddChild(rootEle, computersEle); 56 57 //下面的添加都是根上面一样的思路,希望大家看得明白 58 int cont = self.computers.count; 59 for (int i = 0; i < cont; i++) { 60 NSString *band = [self.computers objectAtIndex:i]; 61 xmlNodePtr computerEle = xmlNewNode(NULL, BAD_CAST("computer")); 62 xmlNodeSetContent(computerEle, (const xmlChar *)[band cStringUsingEncoding:NSUTF8StringEncoding]); 63 xmlAddChild(computersEle, computerEle); 64 } 65 66 xmlNodePtr telephoneEle = xmlNewNode(NULL, BAD_CAST("telephone")); 67 xmlNodeSetContent(telephoneEle, BAD_CAST("Sony Ericsson索爱")); 68 xmlAddChild(rootEle, telephoneEle); 69 70 xmlSaveFormatFileEnc([xmlFilePath cStringUsingEncoding:NSUTF8StringEncoding], xmlDoc, "UTF-8", 1);//保存 71 xmlFreeDoc(xmlDoc);//释放内存 72 73 } 74 75 -(void)libxmlRead{ 76 NSString *xmlFilePath = [@"text.xml" appendFileNameBehindDocument]; 77 xmlTextReaderPtr reader = xmlNewTextReaderFilename((const char *)[xmlFilePath cStringUsingEncoding:NSUTF8StringEncoding]); 78 if (reader) { 79 char *temp; 80 char *value; 81 NSString *element; 82 while (TRUE) { 83 if (!xmlTextReaderRead(reader)){ 84 NSLog(@"退出解析:break"); 85 break;} 86 int type = xmlTextReaderNodeType(reader); 87 if ( type == XML_READER_TYPE_ELEMENT) { 88 temp = (char *)xmlTextReaderConstName(reader);//读取标签 89 element = [NSString stringCToOCUTF8:temp]; 90 91 if ([element isEqualToString:@"computers"]) { 92 value = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST("count")); 93 NSLog(@"解析标签:%@ count=%@",element,[NSString stringCToOCUTF8:value]); 94 95 } 96 97 if ([element isEqualToString:@"computer"]) { 98 value = (char *)xmlTextReaderReadString(reader); 99 NSLog(@"解析标签:%@ value=%@",element,[NSString stringCToOCUTF8:value]); 100 } 101 102 if ([element isEqualToString:@"telephone"]) { 103 value = (char *)xmlTextReaderReadString(reader); 104 NSLog(@"解析标签:%@ value=%@",element,[NSString stringCToOCUTF8:value]); 105 //读取标签内容 106 } 107 } 108 109 //读取Tag的内容 110 if (type == XML_READER_TYPE_TEXT) { 111 temp = (char*)xmlTextReaderConstValue(reader); 112 NSLog(@"XML_READER_TYPE_TEXT:%@",[NSString stringCToOCUTF8:temp]); 113 } 114 115 if (type == XML_READER_TYPE_END_ELEMENT) { 116 117 } 118 119 120 } 121 } 122 123 xmlFreeTextReader(reader); 124 } 125 126 xmlXPathObjectPtr get_nodeset(xmlDocPtr doc, const xmlChar *xpath) { 127 xmlXPathContextPtr context; 128 xmlXPathObjectPtr result; 129 context = xmlXPathNewContext(doc); 130 if (context == NULL) { 131 printf("context is NULL/n"); 132 return NULL; 133 } 134 135 result = xmlXPathEvalExpression(xpath, context); 136 xmlXPathFreeContext(context); 137 if (result == NULL) { 138 printf("xmlXPathEvalExpression return NULL/n"); 139 return NULL; 140 } 141 if (xmlXPathNodeSetIsEmpty(result->nodesetval)) { 142 xmlXPathFreeObject(result); 143 printf("nodeset is empty/n"); 144 return NULL; 145 } 146 return result; 147 } 148 149 -(void)libxmlUpdate{//使用xpath解析得到一个节点,然后再更新内容 150 NSString *xmlFilePath = [@"text.xml" appendFileNameBehindDocument];//文件路径 151 152 xmlChar *xpath = BAD_CAST("/vincent/computers/computer");//xpath的正则表达式 153 154 //得到一个xmlDocPtr 其实xmlDocPtr就是一个指向结构体的指针 155 xmlDocPtr xmlDoc = xmlReadFile((char *)[xmlFilePath cStringUsingEncoding:NSUTF8StringEncoding], "UTF-8", 1); 156 xmlNodePtr curNode; 157 158 //get_nodeset方法是上面的一个方法,不是libxml里面的方法 159 xmlXPathObjectPtr app_result = get_nodeset(xmlDoc,xpath); 160 if (app_result) { 161 //得到查询出来节点的聚合(set) 162 xmlNodeSetPtr nodeSet = app_result -> nodesetval; 163 164 //nodeSet -> nodeNr 是访问nodeSet里面nodeNr的一个属性 nodeNr就是查出来的节点个数 165 for (int i=0; i< nodeSet -> nodeNr; i++) { 166 curNode = nodeSet -> nodeTab[i];//遍历节点 167 168 //得到节点里面的内容 169 char *temp = (char *)xmlNodeGetContent(curNode); 170 171 //输出节点内容 stringCToOCUTF8这个方法是本人自己写的,将char*转成NSString 172 NSLog(@"%@",[NSString stringCToOCUTF8:temp ]); 173 if (i == 0) { 174 //改变第一个computer节点的内容然后保存 175 xmlNodeSetContent(curNode,BAD_CAST("MacBook Air")); 176 xmlSaveFormatFileEnc([xmlFilePath cStringUsingEncoding:NSUTF8StringEncoding], xmlDoc, "UTF-8", 1); 177 } 178 } 179 } 180 xmlXPathFreeObject(app_result);//释放内存 181 xmlFreeDoc(xmlDoc); 182 } 183 184 185 186 @end

 

posted @ 2013-07-29 16:56  Vincent_Guo  阅读(1014)  评论(0编辑  收藏  举报