lynch

C++ libxml2编程基础(Ubuntu系统)

    Libxml2 是一个xml c语言版的解析器,本来是为Gnome项目开发的工具,是一个基于MIT License的免费开源软件。它除了支持c语言版以外,还支持c++、PHP、Pascal、Ruby、Tcl等语言的绑定,能在Windows、Linux、Solaris、MacOsX等平台上运行。功能还是相当强大的,相信满足一般用户需求没有任何问题。
   本文主要简单介绍一下libxml2在linux下的C++使用的基础,操作系统为Ubuntu。 
   一、libxml2的安装
    1、下载libxml2
           地址ftp://xmlsoft.org/libxml2/,这里选择的是libxml2-2.8.0.tar.gz
    2、解压
  1. tar zxvf libxml2-2.8.0.tar.gz
    3、配置安装
  1. ./configure
  2. make
  3. sudo make install
    4、安装libxml-dev
  1. sudo apt-get install libxml2-dev
    5、把libxml2下的libxml拷贝一份到libxml2所在的目录
  1. sudo cp -/usr/include/libxml2/libxml /usr/include/libxml
    6、包含libxml2的测试程序在编译的时候需要引用xml2库,比如测试程序test.cpp,则在编译的时候应该:
  1. g++ test.cpp -lxml2
   二、libxml2常用数据类型
   xmlChar是libxml2中的字符类型,在库中的所有字符,字符串都是基于这个数据类型的。
   xmlChar*是指针类型,很多函数都会返回一个动态分配的内存的xmlChar*类型的变量,因此,在使用这类函数时要记得释放内存,否则会导致内存泄漏,例如这样的用法:
  1. xmlChar *name = xmlNodeGetContent(CurNode);
  2. strcpy(data.name, name);
  3. xmlFree(name);
    xmlDoc、 xmlDocPtr       //文档对象结构体及指针
    xmlNode、 xmlNodePtr   //节点对象结构体及节点指针
    xmlAttr、 xmlAttrPtr      //节点属性的结构体及其指针
    xmlNs、 xmlNsPtr          //节点命名空间的结构及指针
    BAD_CAST                   //一个宏定义,事实上它即是xmlChar*类型
    三、libxml2常用函数
    1、文档相关函数
          int xmlKeepBlankDefault(int val);     //设置是否忽略空白的节点,在解析之前一般要调用,默认值为0,最好设置成为1
          xmlDocPtr    xmlParseFile(const *filename);   //分析一个xml文件,并返回一个xml文档的对象指针
          xmlReadFile            //读入一个带有某种编码的xml文档,并返回一个文档指针
          xmlSaveFile            //将文档以默认方式保存
          xmlSaveFormatFileEnc   //可将文档以某种编码/格式的方式进行保存
          xmlFreeDoc         //释放文档指针    注意:当调用此函数时,该文档所包含的所有节点内存都将被自动释放。一般来说,一个文档中所有的节点都应该动态分配然后加入文档,然后调用xmlFreeDoc函数一次性的释放所有节点动态分配的内存;但是当节点从文档中移除时,就需要调用xmlFreeNode或者是xmlFreeNodeList。
    2、根节点相关函数
          xmlNodePtr  xmlDocGetRootElement(xmlDocPtr  doc);    //获得文档的根节点
          xmlNodePtr xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root);   //设置文档的根节点
    3、创建子节点相关函数
          xmlNodePtr   xmlNewNode(xmlNsPtr ns, const xmlChar *name);   //创建一个新节点
          xmlNodePtr   xmlNewChild(xmlNodePtr  parent, xmlNsPtr ns, const xmlChar *name, const xmlChar *content);    // 创建一个新的字节点
          xmlNodePtr   xmlCopyNode(const xmlNodePtr curNode, int extended);    //复制当前节点
          xmlNodeSetContent                         //设置节点内容
          xmlNodeGetContent                        //获取节点内容
          xmlNodeListGetString                     //获取字符串
    4、添加字节点相关函数
          xmlNodePtr   xmlAddChild(xmlNodePtr parent, xmlNodePtr curNode);  //给指定的节点添加子节点
          xmlNodePtr   xmlAddNextSibling(xmlNodePtr curNode, xmlNodePtr brother);   //添加兄弟节点到后面
          xmlNodePtr   xmlAddPrevSibling(xmlNodePtr curNode, xmlNodePtr brother);   //添加兄弟节点到前面
          xmlNodePtr   xmlAddSibling(xmlNodePtr curNode, xmlNodePtr brother);   //添加一个兄弟节点
    5、属性相关函数
          xmlAttrPtr  xmlNewProp(xmlNodePtr curNode, const xmlChar *name, const xmlChar *value);//创建新节点属性
          xmlAttrPtr  xmlSetProp(xmlNodePtr curNode, const xmlChar *name, const xmlChar *value);//设置新节点属性
          xmlAttrPtr  *xmlGetProp(xmlNodePtr curNode, const xmlChar *name, const xmlChar *value);//读取节点属性  
    6、使用XPATH查找xml文档
         使用XPATH的流程如下:
          1、定义一个XPATH的上下文指针xmlXPathContextPtr context,并且使用函数xmlXPathNewContext来初始化该指针;
          2、定义一个XPATH的对象指针xmlXPathObjectPtr obj,并使用函数xmlXPathEvalExpression来计算XPATH的表达式,得到查询结果,将结果存入对象指针当中;
          3、使用obj->nodesetval得到节点集合指针,在其中包含了所有查询到的XPATH节点;
          4、使用函数xmlXPathFreeContext来释放上下文指针;
          5、最后使用函数xmlXPathFreeObject释放XPATH对象指针。
    四、XML文件创建

  1.  #include<iostream> 
  2.  #include<libxml/parser.h> 
  3.  #include<libxml/xpath.h> 
  4.  #include<libxml/tree.h> 
  5.                                                                        
  6.  using namespace std; 
  7.                                                                        
  8.  int main(){ 
  9.      xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0"); 
  10.      xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"root"); 
  11.      //set root node 
  12.      xmlDocSetRootElement(doc,root_node); 
  13.      //create nodes under root node 
  14.      xmlNewTextChild(root_node,NULL,BAD_CAST"IP",BAD_CAST"192.168.1.116");
  15.      xmlNewTextChild(root_node,NULL,BAD_CAST"Port",BAD_CAST"65535"); 
  16.      xmlNewTextChild(root_node,NULL,BAD_CAST"num",BAD_CAST"1000"); 
  17.      //create a new node,set its content and attributes,then add it to root node
  18.      xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2"); 
  19.      xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT"); 
  20.      //add node to root node 
  21.      xmlAddChild(root_node,node); 
  22.      xmlAddChild(node,content); 
  23.      xmlNewProp(node,BAD_CAST"attribute",BAD_CAST"yes"); 
  24.      //create a son node and a grandson one 
  25.      node = xmlNewNode(NULL,BAD_CAST"son"); 
  26.      xmlAddChild(root_node,node); 
  27.      xmlNodePtr grandson = xmlNewNode(NULL,BAD_CAST"grandson"); 
  28.      xmlAddChild(node,grandson); 
  29.      xmlAddChild(grandson,xmlNewText(BAD_CAST"This is a grandson node"));
  30.      //save xml doc 
  31.      int ret = xmlSaveFile("create.xml",doc); 
  32.      if(ret != -1){ 
  33.          cout<<"A xml doc is created;Write in "<<ret<<" bytes"<<endl; 
  34.      } 
  35.      xmlFreeDoc(doc); 
  36.      return 0; 
  37.  }
            编译:g++  build.cc -lxml2
            运行:打开create.xml

  1. <?xml version="1.0"?> 
  2.    <root> 
  3.        <IP>192.168.1.116</IP> 
  4.        <Port>65535</Port> 
  5.        <num>1000</num> 
  6.        <node2 attribute="yes">NODE CONTENT</node2> 
  7.        <son> 
  8.            <grandson>This is a grandson node</grandson> 
  9.        <son> 
  10.    </root>
    五、XML文件解析
     xml文件

  1. <?xml version="1.0"?> 
  2.    <root> 
  3.        <IP>192.168.1.116</IP> 
  4.        <Port>65535</Port> 
  5.        <num>1000</num> 
  6.        <node2 attribute="yes">NODE CONTENT</node2> 
  7.        <son> 
  8.            <grandson>This is a grandson node</grandson> 
  9.        <son> 
  10.    </root>
     解析代码:

  1. #include<iostream> 
  2.  #include<libxml/parser.h> 
  3.  //#include<libxml/xmlmemory.h> 
  4.  #include<string> 
  5.                                                                        
  6.  using namespace std; 
  7.                                                                        
  8.  const char* xmlConfig="create.xml"; 
  9.                                                                        
  10.  int main(){ 
  11.      xmlDocPtr doc; 
  12.      xmlNodePtr curNode; 
  13.      xmlChar* szKey; 
  14.                                                                        
  15.      doc = xmlParseFile(xmlConfig); 
  16.      if(doc == NULL){ 
  17.          cout<<"Document not parsed successfully!"<<endl; 
  18.          return -1; 
  19.      } 
  20.      //cout<<"Document parsed successfully!"<<endl; 
  21.      curNode = xmlDocGetRootElement(doc); 
  22.      if(curNode == NULL){ 
  23.          cout<<"empty document.\n"<<endl; 
  24.          xmlFreeDoc(doc); 
  25.          return -1; 
  26.      } 
  27.      //cout<<"xmlDocGetRootElement OK.\n"<<endl; 
  28.      if(xmlStrcmp(curNode->name,BAD_CAST"root")){ 
  29.          cerr<<"root node is not 'root'"<<endl; 
  30.          xmlFreeDoc(doc); 
  31.          return -1; 
  32.      } 
  33.      curNode = curNode->xmlChildrenNode; 
  34.      xmlNodePtr propNodePtr = curNode; 
  35.      while(NULL != curNode){ 
  36.          if((!xmlStrcmp(curNode->name,(const xmlChar*)"IP"))){ 
  37.              szKey = xmlNodeGetContent(curNode); 
  38.              cout<<"IP:"<<szKey<<endl; 
  39.              //string s((char*)szKey); 
  40.              xmlFree(szKey); 
  41.              //cout<<s<<endl; 
  42.          }else if((!xmlStrcmp(curNode->name,(const xmlChar*)"Port"))){
  43.              szKey = xmlNodeGetContent(curNode); 
  44.              cout<<"Port:"<<szKey<<endl; 
  45.              xmlFree(szKey); 
  46.          }else if((!xmlStrcmp(curNode->name,(const xmlChar*)"num"))){ 
  47.              szKey = xmlNodeGetContent(curNode); 
  48.              cout<<"num:"<<szKey<<endl; 
  49.              xmlFree(szKey); 
  50.          } else if((!xmlStrcmp(curNode->name,(const xmlChar*)"node2"))){
  51.              szKey = xmlNodeGetContent(curNode); 
  52.              cout<<"node2:"<<szKey<<endl; 
  53.              xmlFree(szKey); 
  54.              // get attributes 
  55.              szKey = xmlGetProp(curNode,(const xmlChar*)"attribute"); 
  56.              cout<<"node2->attribute:"<<szKey<<endl; 
  57.              xmlFree(szKey); 
  58.          } 
  59.          curNode= curNode->next; 
  60.      } 
  61.                                                                        
  62.      return 0; 
  63.  }

posted on 2012-12-14 14:08 董三 阅读(2328) 评论(1)  编辑 收藏 引用 所属分类: C++

评论

# re: C++ libxml2编程基础(Ubuntu系统) 2012-12-14 19:58 eryar

Good!
Mark...  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

博客友

搜索

最新评论

阅读排行榜

评论排行榜