zoukankan      html  css  js  c++  java
  • libxml的使用(4)--xpath搜索节点树

     

    在libxml的tutorial中介绍了一种用关键字查找节点的方法,这种方法将使用打xpath系列API。由于我才刚刚接触libxml,所以我对xpath的认识也仅仅是在tutorial提供的功能之内了。废话少说,直接进入整体。

    我们在操作xml文件是经常需要根据特定的条件查找一系列的节点,为了实现这样的功能,我们需要一个xmlXPathContextPtr和一个expression。我们调用xmlXPathEvalExpression函数来得到一个xmlXPathObjectPtr指针,这个指针包含了一个xmlNodeSetPtr,其中有一个变量nodeTab是我们所需要的节点数组。

    [cpp] view plaincopyprint?
     
     
    1. xmlXPathObjectPtr ret = NULL;  
    2. xmlXPathContextPtr con = NULL;  
    3.   
    4. con = xmlXPathNewContext(doc);  
    5. ret = xmlXPathEvalExpression((xmlChar*)expr, con);  
    6. xmlXPathFreeContext(con);  

    这样我们就得到了查询的结果了。expr是查询的条件,tutorial给的例子里,这个条件是“//keyword”,表示找出所有名称为keyword的节点。至于其他的条件,我现在还不知道。

    得到了查询的结果,我们就要对结果进行处理。

    [cpp] view plaincopyprint?
     
     
    1. if(NULL == ret) {  
    2.     fprintf(stderr, "eval func error ");  
    3.     exit(1);  
    4. }  
    5. if(xmlXPathNodeSetIsEmpty(ret->nodesetval)){  
    6.     fprintf(stderr, "node set empty ");  
    7.     xmlXPathFreeObject(ret);  
    8.     exit(1);  
    9. }  
    10. xmlNodeSetPtr nodeset = ret->nodesetval;  
    11. int i;  
    12. for(i = 0; i < nodeset->nodeNr; i ++) {  
    13.     //handle the node  
    14. }  
    15. xmlXPathFreeObject(ret);  

    下面是一个程序的实例。用于提取出网页中的链接:

    web.html

    [html] view plaincopyprint?
     
     
    1. <html>  
    2.     <head>  
    3.         <title>web</title>  
    4.     </head>  
    5.     <body>  
    6.         <href="www.baidu.com">baidu</a>  
    7.         <href="www.google.com">Google</a>  
    8.     </body>  
    9. </html>  

    link.c

    [cpp] view plaincopyprint?
     
     
    1. #include <stdio.h>  
    2. #include <string.h>  
    3. #include <stdlib.h>  
    4. #include <libxml/parser.h>  
    5. #include <libxml/xpath.h>  
    6.   
    7. static xmlDocPtr  
    8. getDocPtr(char* docname) {  
    9.     xmlDocPtr doc = NULL;  
    10.     xmlKeepBlanksDefault(0);  
    11.   
    12.     doc = xmlParseFile(docname);  
    13.     if(NULL == doc) {  
    14.         fprintf(stderr, "document cannot be parsed! ");  
    15.         exit(1);  
    16.     }  
    17.     return doc;  
    18. }  
    19.   
    20. static xmlXPathObjectPtr  
    21. getXPathObjectPtr(xmlDocPtr doc, xmlChar* xpath_exp) {  
    22.     xmlXPathObjectPtr result;  
    23.     xmlXPathContextPtr context;  
    24.       
    25.     context = xmlXPathNewContext(doc);  
    26.     result = xmlXPathEvalExpression((const xmlChar*)xpath_exp, context);  
    27.     xmlXPathFreeContext(context);  
    28.   
    29.     if(NULL == result) {  
    30.         fprintf(stderr, "eval expression error! ");  
    31.         return NULL;  
    32.     }  
    33.   
    34.     if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {  
    35.         fprintf(stderr, "empty node set! ");  
    36.         xmlXPathFreeObject(result);  
    37.         return NULL;  
    38.     }  
    39.     return result;  
    40. }  
    41.   
    42. int main() {  
    43.     char* docname = "web.html";  
    44.     xmlDocPtr doc = NULL;  
    45.     xmlXPathObjectPtr xpath_obj = NULL;  
    46.     xmlNodeSetPtr nodeset = NULL;  
    47.     xmlChar* xpath_exp = (xmlChar*)"//a";  
    48.     xmlChar* uri;  
    49.   
    50.     doc = getDocPtr(docname);  
    51.   
    52.     xpath_obj = getXPathObjectPtr(doc, xpath_exp);  
    53.   
    54.     if(NULL != xpath_obj) {  
    55.         nodeset = xpath_obj->nodesetval;  
    56.         int i = 0;  
    57.         for(i = 0; i < nodeset->nodeNr; i ++) {  
    58.             uri = xmlGetProp(nodeset->nodeTab[i],(const xmlChar*)"href");  
    59.             printf("link address:%s ",uri);  
    60.             xmlFree(uri);  
    61.         }  
    62.         xmlXPathFreeObject(xpath_obj);  
    63.     }  
    64.     xmlFreeDoc(doc);  
    65.     xmlCleanupParser();  
    66.       
    67.     return 1;  
    68. }  

    输出结果为:
    [html] view plaincopyprint?
     
     
    1. link address:www.baidu.com  
    2. link address:www.google.com  
     
     
  • 相关阅读:
    Java学习笔记之——break 和continue
    Java学习笔记之——循环语句
    Java学习笔记之——switch-case条件结构
    Java学习笔记之——if条件语句和三目运算符
    Java学习笔记之——变量与数据类型、运算符
    supervisor-program配置
    应用节点使用管理节点做代理访问互联网的方法
    运营商-技术问题汇总
    galera cluster,mysql配置wsrep_notify_cmd参数,增加邮件告警
    while循环中出现ssh导致读取文件错误
  • 原文地址:https://www.cnblogs.com/fire909090/p/6798173.html
Copyright © 2011-2022 走看看