zoukankan      html  css  js  c++  java
  • [libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]

    场景:

    1.在软件需要保存一些配置项时,使用数据库的话比较复杂,查看内容也不容易.纯文本文件对utf8字符支持也不好.

    2.这时候使用xml是最佳选择,使用跨平台库libxml2。

    3.基于xpath的保存方式对保存局部内容非常方便。

    4.参考例子xpath2.c

      1     #include <stdio.h>  
      2     #include <assert.h>  
      3     #include <string>  
      4     #include <iostream>  
      5     #include <map>  
      6       
      7     #include "libxml/tree.h"  
      8     #include "libxml/parser.h"  
      9     #include "libxml/xpath.h"  
     10     #include "libxml/xpathInternals.h"  
     11     #include "libxml/xmlsave.h"  
     12       
     13     using namespace std;  
     14       
     15     static void _UpdateXpathNodes(xmlNodeSetPtr nodes, const xmlChar* value)   
     16     {  
     17         int size;  
     18         int i;  
     19           
     20         assert(value);  
     21         size = (nodes) ? nodes->nodeNr : 0;  
     22         for(i = size - 1; i >= 0; i--)   
     23         {  
     24             assert(nodes->nodeTab[i]);  
     25             xmlNodeSetContent(nodes->nodeTab[i], value);  
     26             if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)  
     27             {  
     28                 nodes->nodeTab[i] = NULL;  
     29             }  
     30        }  
     31     }  
     32       
     33     static int _UpdateWithXpath(xmlXPathContextPtr xpathCtx,const char* key,const char* value)  
     34     {  
     35         xmlXPathObjectPtr xpathObj;  
     36           
     37         xpathObj = xmlXPathEvalExpression(BAD_CAST key, xpathCtx);  
     38         if(!xpathObj)  
     39         {  
     40             fprintf(stderr,"Error: unable to evaluate xpath expression "%s"
    ", key);  
     41             return -1;  
     42         }  
     43         _UpdateXpathNodes(xpathObj->nodesetval, BAD_CAST value);  
     44         xmlXPathFreeObject(xpathObj);  
     45         return 0;  
     46     }  
     47       
     48     static int _UpdateXml(const char* path,map<string,string>& keyValue)  
     49     {  
     50         xmlDocPtr doc;  
     51         xmlXPathContextPtr xpathCtx;   
     52         doc = xmlParseFile(path);  
     53         if (!doc)  
     54         {  
     55             fprintf(stderr, "Error: unable to parse file "%s"
    ", path);  
     56             return(-1);  
     57         }  
     58       
     59         /* Create xpath evaluation context */  
     60         xpathCtx = xmlXPathNewContext(doc);  
     61         //1.注意,这里根Node有声明xmlns,那么必须加下边这句,相应的xpath要加前缀 /c:container/c:rootfiles  
     62         //xmlXPathRegisterNs(xpathCtx,BAD_CAST"c",BAD_CAST"urn:oasis:names:tc:opendocument:xmlns:container");  
     63         if(!xpathCtx)  
     64         {  
     65             fprintf(stderr,"Error: unable to create new XPath context
    ");  
     66             xmlFreeDoc(doc);   
     67             return(-1);  
     68         }  
     69         //3.update  
     70         map<string,string>::iterator iter;  
     71         map<string,string>::iterator end = keyValue.end();  
     72         for(iter = keyValue.begin();iter!= end;iter++)  
     73         {  
     74             cout << "word: " << iter->first << ", count: " << iter->second << endl;  
     75             _UpdateWithXpath(xpathCtx,iter->first.c_str(),iter->second.c_str());  
     76         }  
     77           
     78         xmlXPathFreeContext(xpathCtx);  
     79         //4.save  
     80         xmlSaveCtxtPtr saveCtxtPtx = xmlSaveToFilename(path,"UTF-8",XML_SAVE_FORMAT);  
     81         if(!saveCtxtPtx)  
     82         {  
     83             xmlFreeDoc(doc);  
     84             return -1;  
     85         }  
     86       
     87         if(-1 == xmlSaveDoc(saveCtxtPtx,doc))  
     88         {  
     89             xmlFreeDoc(doc);  
     90             return -1;  
     91         }  
     92         xmlSaveClose(saveCtxtPtx);  
     93         //xmlDocDump(stdout, doc);  
     94         //5.free  
     95         xmlFreeDoc(doc);   
     96         return 0;  
     97     }  
     98       
     99     int UpdateXml(const char* path,map<string,string>& keyValue)  
    100     {  
    101         /* Init libxml */       
    102         xmlInitParser();  
    103         int res  = _UpdateXml(path,keyValue);  
    104         xmlCleanupParser();  
    105         return res;  
    106     }  
    107       
    108     int main(int argc, char *argv[])  
    109     {  
    110         printf("Hello, world
    ");  
    111         map<string,string> m;  
    112         m["/doc/parent/discarded/@info"] = string("info attri");  
    113         m["/doc/parent/discarded[2]"] = string("change second discarded text 中文");  
    114         int ret = UpdateXml("xpath2.res",m);  
    115         assert(!ret);  
    116         ret = UpdateXml("xpath2.res",m);  
    117         assert(!ret);  
    118         ret = UpdateXml("xpath2.res",m);  
    119         assert(!ret);  
    120         return 0;  
    121     }  

    xpath2.res

        <?xml version="1.0" encoding="UTF-8"?>  
        <doc>  
          <parent>  
            <discarded info="test">discarded</discarded>  
            <preserved/>  
            This text node must be discarded  
            <discarded>test</discarded>  
            <preserved>  
              content1  
              <child1/>  
              <child2>content2</child2>  
              <preserved>too</preserved>  
              <child2>content3</child2>  
              <preserved/>  
              <child2>content4</child2>  
              <preserved/>  
              <child2>content5</child2>  
              content6  
            </preserved>  
          </parent>  
        </doc>  

    xpath2.res

        <?xml version="1.0" encoding="UTF-8"?>  
        <doc>  
          <parent>  
            <discarded info="info attri">discarded</discarded>  
            <preserved/>  
            This text node must be discarded  
            <discarded>change second discarded text 中文</discarded>  
            <preserved>  
              content1  
              <child1/>  
              <child2>content2</child2>  
              <preserved>too</preserved>  
              <child2>content3</child2>  
              <preserved/>  
              <child2>content4</child2>  
              <preserved/>  
              <child2>content5</child2>  
              content6  
            </preserved>  
          </parent>  
        </doc>  
    View Code
  • 相关阅读:
    header
    panel----单个基础版
    vue-demo
    js不同类型变量比较
    reset.css
    关于各个浏览器的兼容问题
    git
    AMD与CMD区别
    喜欢前端的看过来哦
    js中数组去重的几种方法
  • 原文地址:https://www.cnblogs.com/catgatp/p/8012740.html
Copyright © 2011-2022 走看看