libxml2使用解析XML和查找

因一个应用里需要解XML,tinyxml也许还可以,但是C++的,应用在C下,所以还是找一些C的,找了几个比较小的库解析使用都感觉不怎么样,最后还是使用libxml2吧,因同事应用里用也用了这个,木已成舟啊!!!,最后大家都用so文件。

libxml2编译

在其网站上下载libxml2,编译很简单,只要指定几个参数就可以了。如下:

第一步:

 ./configure --prefix=$HOME/libxml2_3531  --host=arm-hisiv100nptl-linux --with-debug=off

--host参数就是指定我使用的编译器,这里指定一个前缀就行了,应我用的是arm-hisiv100nptl-linux-gcc。

--prefix 指定了编译后保存的目录

第二步:

make

第三步:

make install

 

这样就好了,在指定的目录里就会有相应的动态和静态的库产生。

 

libxml2的使用

我用的功能其实很少,只是解析和查找,更改XML文档都没有用到,网上很多小的库,都是只有解析的功能,有的也有实现XPATH的,这样查找节点会很方便。

 

libxml解析XML

我的XML是从网络上接收到的SOAP包,XML都不会太大,我用的xmlParseMemory方法,当然也可以从文件里读XML。

如,我把收到的SOAP把XML放在一个BUFF里,再调用xmlParseMemory 解析,xmlParseMemory返回一个xmlDocPtr指针,这样我们就可认对一个XML文档做很多操作了,xmlXPathContext主要是用XPath来查找搜索XML节点的,有了这家伙,操作很灵活,所以找库最好找一个实现了XPATH的,可以上W3C学习一下XPATH的内容,很简单,用到XPATH的话,你可能还需要学习理解XML的命名空间,这个在W3C上也有资料。

如下的应用:

1
2
3
4
5
6
7
8
xmlDocPtr doc;
xmlXPathContextPtr context;
char *MemoryBuff;
int size;
doc = xmlParseMemory(MemoryBuff,size);
  context = xmlXPathNewContext(doc);
for (i=0;i<MAX-NS;i++)   //把命名空间注册,如果你解的XML里有命名空间的话,这一步就是需要的
      xmlXPathRegisterNs(context,NS-NAME[i],NS[i])

 


libxml查找节点

查找节点可以使用如下的一个函数,来自LIBXML的文档里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
xmlXPathContextPtr get_nodeset(xmlDocPtr doc, xmlChar *xpath){
  xmlXPathObjectPtr result;
  if (context == NULL) {
   printf ( "Error in xmlXPathNewContext\n" );
   return NULL;
  }
  result = xmlXPathEvalExpression(xpath, context);
  if (result == NULL) {
   printf ( "Error in xmlXPathEvalExpression\n" );
   return NULL;
  }
  if (xmlXPathNodeSetIsEmpty(result->nodesetval)){
   xmlXPathFreeObject(result);
     printf ( "No result\n" );
   return NULL;
  }
  //printf("result->nodesetval->nodeMax:%d\n",result->nodesetval->nodeMax);
  return result;
}

注意,上面返回的可能是多个节点,如果你只要查找其中的第一个节点,使问题简化,可以下面这样改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xmlNodePtr get_first_node(xmlDocPtr doc,xmlChar *xpath){
     xmlNodePtr result;
     xmlXPathObjectPtr path_ptr;
     if (context == NULL) {
         printf ( "Error in xmlXPathNewContext\n" );
         return NULL;
     }
     path_ptr = xmlXPathEvalExpression(xpath, context);
     if (path_ptr == NULL) {
         printf ( "Error in xmlXPathEvalExpression\n" );
         return NULL;
     }
     if (xmlXPathNodeSetIsEmpty(path_ptr->nodesetval)){
         xmlXPathFreeObject(path_ptr);
                 printf ( "No result,path:%s\n" ,xpath);
         return NULL;
     }
     if (path_ptr->nodesetval->nodeNr == 0)
         return NULL;
     result = path_ptr->nodesetval->nodeTab[0];
     //printf("result->nodesetval->nodeMax:%d\n",result->nodesetval->nodeMax);
     return result;  
}

看上面的18行,你应去了解一下nodesetval这个结构,就很明白了,nodeNr记录的就是查找到的节点数.

如果知道了XPATH的知识,其实我们在查找节点时,可以利用XPATH的规则只返回第一个节点,或第二个节点...这样的指定。

假如我们解出了一个XML文档:

现在我们有了如下的指针

xmlDocPtr doc 。

//要查找一个节点,可以如下调用:

xmlNodePtr node_ptr = NULL;
 if(docPtr){
  node_ptr = get_first_node(doc ,"//SOAP-ENV:Body/SOAP-ENV:Fault/SOAP-ENV:Reason/SOAP-ENV:Text"); 
  if(node_ptr){
    print_debug_info("Back Failed,Reason text:%s",xmlNodeGetContent(node_ptr));
  }
 }

 这样会查找 XML文档中是否有 SOAP-ENV:Body/SOAP-ENV:Fault/SOAP-ENV:Reason/SOAP-ENV:Text 这个路径节点 。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值