• XML_CPP_资料_libXml2_01_Code


    ZC: 这里的代码,就是 http://www.cnblogs.com/cppskill/p/6207609.html(我的文章"XML_CPP_资料_libXml2_01 - CppSkill - 博客园.html")里面的代码...

    1、创建xml文档

      1.1、CreateXmlFile.cpp

    /********************************************************************
        created:    2007/11/09
        created:    9:11:2007   15:34
        filename:    CreateXmlFile.cpp
        author:        Wang xuebin 
        depend:        libxml2.lib 
        build:        nmake TARGET_NAME=CreateXmlFile
        
        purpose:    创建一个xml文件
    *********************************************************************/
    
    #include <stdio.h>
    #include <libxml/parser.h>
    #include <libxml/tree.h>
    #include <iostream.h>
    
    int main()
    {
        //定义文档和节点指针
        xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
        xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"root");
        
        //设置根节点
        xmlDocSetRootElement(doc,root_node);
        
    
        //在根节点中直接创建节点
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");
    
        //创建一个节点,设置其内容和属性,然后加入根结点
        xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");
        xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");
        xmlAddChild(root_node,node);
        xmlAddChild(node,content);
        xmlNewProp(node,BAD_CAST"attribute",BAD_CAST "yes");
    
        //创建一个儿子和孙子节点
        node = xmlNewNode(NULL, BAD_CAST "son");
        xmlAddChild(root_node,node);
        xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson");
        xmlAddChild(node,grandson);
        xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson node"));
    
        //存储xml文档
        int nRel = xmlSaveFile("CreatedXml.xml",doc);
        if (nRel != -1)
        {
            cout<<"一个xml文档被创建,写入"<<nRel<<"个字节"<<endl;
        }
    
        //释放文档内节点动态申请的内存
        xmlFreeDoc(doc);
        return 1;
    }

      1.2、CreatedXml.xml

    <?xml version="1.0"?>
    <root>
        <newNode1>newNode1 content</newNode1>
        <newNode2>newNode2 content</newNode2>
        <newNode3>newNode3 content</newNode3>
        <node2 attribute="yes">NODE CONTENT</node2>
        <son>
            <grandson>This is a grandson node</grandson>
        </son>
    </root>

    2、解析xml文档

      2.1、ParseXmlFile.cpp

    /********************************************************************
        created:    2007/11/15
        created:    15:11:2007   11:47
        filename:    ParseXmlFile.cpp
        author:        Wang xuebin 
        depend:        libxml2.lib
        build:        nmake TARGET_NAME=ParseXmlFile
        
        purpose:    解析xml文件
    *********************************************************************/
    
    #include <libxml/parser.h>
    #include <iostream.h>
    
    int main(int argc, char* argv[])
    {
        xmlDocPtr doc;            //定义解析文档指针 
        xmlNodePtr curNode;        //定义结点指针(你需要它为了在各个结点间移动) 
        xmlChar *szKey;            //临时字符串变量
    
        char *szDocName;
        if (argc <= 1)  
        {
            printf("Usage: %s docname
    ", argv[0]);
            return(0);
        }
        szDocName = argv[1];
    
        doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);  //解析文件 
        
        //检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。
        //一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。
        //如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中.
        if (NULL == doc) 
        {     
            fprintf(stderr,"Document not parsed successfully. 
    ");     
            return -1; 
        } 
        
        curNode = xmlDocGetRootElement(doc);  //确定文档根元素
        
        /*检查确认当前文档中包含内容*/ 
        if (NULL == curNode)
        { 
            fprintf(stderr,"empty document
    "); 
            xmlFreeDoc(doc); 
            return -1; 
        } 
        
        /*在这个例子中,我们需要确认文档是正确的类型。“root”是在这个示例中使用文档的根类型。*/
        if (xmlStrcmp(curNode->name, BAD_CAST "root")) 
        {
            fprintf(stderr,"document of the wrong type, root node != root"); 
            xmlFreeDoc(doc); 
            return -1; 
        } 
    
        curNode = curNode->xmlChildrenNode;
        xmlNodePtr propNodePtr = curNode;
        while(curNode != NULL) 
        {
            //取出节点中的内容
            if ((!xmlStrcmp(curNode->name, (const xmlChar *)"newNode1"))) 
            {
                szKey = xmlNodeGetContent(curNode);
                printf("newNode1: %s
    ", szKey); 
                xmlFree(szKey); 
            } 
    
            //查找带有属性attribute的节点
            if (xmlHasProp(curNode,BAD_CAST "attribute"))
            {
                propNodePtr = curNode;
            }
            curNode = curNode->next; 
        } 
    
        //查找属性
        xmlAttrPtr attrPtr = propNodePtr->properties;
        while (attrPtr != NULL)
        {
            if (!xmlStrcmp(attrPtr->name, BAD_CAST "attribute"))
            {
                xmlChar* szAttr = xmlGetProp(propNodePtr,BAD_CAST "attribute");
                cout<<"get attribute = "<<szAttr<<endl;
                xmlFree(szAttr);
            }
            attrPtr = attrPtr->next;
        }
    
        xmlFreeDoc(doc);
        return 0;
    }

      2.2、ParseXmlFile.exe CreatedXml.xml

    3、修改xml文档

      3.1、ChangeXmlFile.cpp

    /********************************************************************
        created:    2007/11/15
        created:    15:11:2007   15:20
        filename:    ChangeXmlFile.cpp
        author:        Wang xuebin 
        depend:        libxml2.lib
        build:        nmake TARGET_NAME=ChangeXmlFile
        
        purpose:    修改XML元素及属性
    *********************************************************************/
    
    #include <libxml/parser.h>
    #include <iostream.h>
    
    int main(int argc, char* argv[])
    {
        xmlDocPtr doc;   //定义解析文档指针 
        xmlNodePtr curNode;  //定义结点指针(你需要它为了在各个结点间移动) 
    
        char *szDocName;
        if (argc <= 1)  
        {
            printf("Usage: %s docname
    ", argv[0]);
            return(0);
        }
        szDocName = argv[1];
    
        doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);  //解析文件 
        
        if (NULL == doc) 
        {     
            fprintf(stderr,"Document not parsed successfully. 
    ");     
            return -1; 
        } 
        
        curNode = xmlDocGetRootElement(doc); 
        /*检查确认当前文档中包含内容*/ 
        if (NULL == curNode) 
        { 
            fprintf(stderr,"empty document
    "); 
            xmlFreeDoc(doc); 
            return -1; 
        } 
    
        curNode = curNode->children;
        while (NULL != curNode)
        {
            //删除newNode1
            if (!xmlStrcmp(curNode->name, BAD_CAST "newNode1"))
            {
                xmlNodePtr tempNode;
                tempNode = curNode->next;
                xmlUnlinkNode(curNode);
                xmlFreeNode(curNode);
                curNode = tempNode;
                continue;
            }
            
            //修改node2的属性值
            if (!xmlStrcmp(curNode->name, BAD_CAST "node2"))
            {
                xmlSetProp(curNode,BAD_CAST "attribute", BAD_CAST "no");
            }
            //修改newNode2的内容
            if (!xmlStrcmp(curNode->name, BAD_CAST "newNode2"))
            {
                xmlNodeSetContent(curNode, BAD_CAST "content changed");
            }
    
            //增加一个属性
            if (!xmlStrcmp(curNode->name, BAD_CAST "newNode3"))
            {
                xmlNewProp(curNode, BAD_CAST "newAttr", BAD_CAST "YES");
            }
    
            //增加一个子节点
            if (!xmlStrcmp(curNode->name, BAD_CAST "son"))
            {
                xmlNewTextChild(curNode, NULL, BAD_CAST "newGrandSon", BAD_CAST "new content");
            }
            
            curNode = curNode->next;
        }
    
        //存储xml文档
        int nRel = xmlSaveFile("ChangedXml.xml",doc);
        if (nRel != -1)
        {
            cout<<"一个xml文档被创建,写入"<<nRel<<"个字节"<<endl;
        }
        xmlFreeDoc(doc); 
        return 0;
    }

      3.2、ChangedXml.xml  (ChangeXmlFile.exe CreatedXml.xml)

    <?xml version="1.0"?>
    <root>
        
        <newNode2>content changed</newNode2>
        <newNode3 newAttr="YES">newNode3 content</newNode3>
        <node2 attribute="no">NODE CONTENT</node2>
        <son>
            <grandson>This is a grandson node</grandson>
        <newGrandSon>new content</newGrandSon></son>
    </root>

    4、使用XPATH查找xml文档

      4.1、XPathForXmlFile.cpp

    /********************************************************************
        created:    2007/11/15
        created:    15:11:2007   16:01
        filename:    XpathForXmlFile.cpp
        author:        Wang xuebin 
        depend:        libxml2.lib
        build:        nmake TARGET_NAME=XPathForXmlFile
        
        purpose:    使用XPATH查找xml文档中的节点
    *********************************************************************/
    
    #include <libxml/parser.h>
    #include <libxml/xpath.h>
    #include <iostream.h>
    
    xmlXPathObjectPtr get_nodeset(xmlDocPtr doc, const xmlChar *szXpath) 
    {
        xmlXPathContextPtr context;        //XPATH上下文指针
        xmlXPathObjectPtr result;        //XPATH对象指针,用来存储查询结果
        
        context = xmlXPathNewContext(doc);        //创建一个XPath上下文指针
        if (context == NULL) 
        {    
            printf("context is NULL
    ");
            return NULL; 
        }
        
        result = xmlXPathEvalExpression(szXpath, context); //查询XPath表达式,得到一个查询结果
        xmlXPathFreeContext(context);                //释放上下文指针
        if (result == NULL) 
        {
            printf("xmlXPathEvalExpression return NULL
    "); 
            return NULL;  
        }
        
        if (xmlXPathNodeSetIsEmpty(result->nodesetval))   //检查查询结果是否为空
        {
            xmlXPathFreeObject(result);
            printf("nodeset is empty
    ");
            return NULL;
        }
        
        return result;    
    }
    
    int main(int argc, char* argv[])
    {
        xmlDocPtr doc = NULL;             //定义解析文档指针 
        xmlNodePtr curNode = NULL;         //定义结点指针(你需要它为了在各个结点间移动) 
    
        char *szDocName = NULL;
        if (argc <= 1)  
        {
            printf("Usage: %s docname
    ", argv[0]);
            return(0);
        }
        szDocName = argv[1];
    
        doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);  //解析文件 
        
        if (NULL == doc) 
        {     
            fprintf(stderr,"Document not parsed successfully. 
    ");     
            return -1; 
        } 
        
        xmlChar *szXpath =BAD_CAST ("/root/node2[@attribute='yes']"); 
        xmlXPathObjectPtr app_result = get_nodeset(doc,szXpath);  //查询并得到结果
        
        if (NULL == app_result) 
        {
            printf("app_result is NULL
    "); 
            return -1;
        }
        xmlChar *szValue = NULL;
        if(app_result) 
        {
            xmlNodeSetPtr nodeset = app_result->nodesetval;
            for (int i = 0; i < nodeset->nodeNr; i++) 
            {
                curNode = nodeset->nodeTab[i];    
                if(curNode != NULL) 
                {
                    szValue = xmlGetProp(curNode,BAD_CAST "attribute");
                    if (szValue != NULL) 
                    {
                        printf("attribute = %s
    ", szValue);
                        xmlFree(szValue);
                    }
                    
                    szValue = xmlNodeGetContent(curNode);
                    if (szValue != NULL) 
                    {
                        printf("content = %s
    ", szValue);
                        xmlFree(szValue);
                    }
                }
            }
            xmlXPathFreeObject (app_result);
        }
        xmlFreeDoc(doc);
        return 0;
    }

      4.2、XpathForXmlFile.exe CreatedXml.xml

    5、用ICONV解决XML中的中文问题

      5.1、wxb_codeConv.c

    /********************************************************************
        created:    2007/11/15
        created:    15:11:2007   10:30
        filename:    wxb_codeConv.c
        author:        Wang xuebin 
        depend:        iconv.lib
        build:        不需要build,被包含到其它源代码中
        
        purpose:    提供从UTF-8到GB2312的内码转换,以及反向的转换
    *********************************************************************/
    
    #include "iconv.h"
    #include <string.h>
    
    //代码转换:从一种编码转为另一种编码   
    int code_convert(char* from_charset, char* to_charset, char* inbuf,
                     int inlen, char* outbuf, int outlen)
    {
        iconv_t cd;
        char** pin = &inbuf;   
        char** pout = &outbuf;
    
        cd = iconv_open(to_charset,from_charset);   
        if(cd == 0)
            return -1;
        memset(outbuf,0,outlen);   
        if(iconv(cd,(const char**)pin,(unsigned int *)&inlen,pout,(unsigned int*)&outlen)
            == -1)
            return -1;   
        iconv_close(cd);
        return 0;   
    }
    
    //UNICODE码转为GB2312码   
    //成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL
    char* u2g(char *inbuf)   
    {
        int nOutLen = 2 * strlen(inbuf) - 1;
        char* szOut = (char*)malloc(nOutLen);
        
        if (-1 == code_convert("utf-8","gb2312",inbuf,strlen(inbuf),szOut,nOutLen))
        {
            free(szOut);
            szOut = NULL;
        }
        return szOut;
    }   
    
    //GB2312码转为UNICODE码   
    //成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL
    char* g2u(char *inbuf)   
    {
        int nOutLen = 2 * strlen(inbuf) - 1;
        char* szOut = (char*)malloc(nOutLen);
        
        if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))
        {
            free(szOut);
            szOut = NULL;
        }
        return szOut;
    }   

      5.2、CreateXmlFile_cn.cpp

    /********************************************************************
        created:    2007/11/17
        created:    9:11:2007   15:34
        filename:    CreateXmlFile.cpp
        author:        Wang xuebin 
        depend:        libxml2.lib iconv.lib
        build:        nmake TARGET_NAME=CreateXmlFile_cn
        
        purpose:    创建一个xml文件,其中包含中文
    *********************************************************************/
    
    #include <stdio.h>
    #include <libxml/parser.h>
    #include <libxml/tree.h>
    #include <iostream.h>
    #include "wxb_codeConv.c"  //自己写的编码转换函数
    
    int main(int argc, char **argv)
    {
        //定义文档和节点指针
        xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
        xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"root");
        
        //设置根节点
        xmlDocSetRootElement(doc,root_node);
        
        //一个中文字符串转换为UTF-8字符串,然后写入
        char* szOut = g2u("节点1的内容");
    
        //在根节点中直接创建节点
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");
        xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");
    
        xmlNewChild(root_node, NULL, BAD_CAST "node1",BAD_CAST szOut);
        free(szOut);
    
        //创建一个节点,设置其内容和属性,然后加入根结点
        xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");
        xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");
        xmlAddChild(root_node,node);
        xmlAddChild(node,content);
        szOut = g2u("属性值");
        xmlNewProp(node,BAD_CAST"attribute",BAD_CAST szOut);
        free(szOut);
    
        //创建一个中文节点
        szOut = g2u("中文节点");
        xmlNewChild(root_node, NULL, BAD_CAST szOut,BAD_CAST "content of chinese node");
        free(szOut);
    
        //存储xml文档
        int nRel = xmlSaveFormatFileEnc("CreatedXml_cn.xml",doc,"GB2312",1);
        if (nRel != -1)
        {
            cout<<"一个xml文档被创建,写入"<<nRel<<"个字节"<<endl;
        }
    
        xmlFreeDoc(doc);
    
        return 1;
    }

      5.3、CreatedXml_cn.xml

    <?xml version="1.0" encoding="GB2312"?>
    <root>
      <newNode1>newNode1 content</newNode1>
      <newNode2>newNode2 content</newNode2>
      <newNode3>newNode3 content</newNode3>
      <node1>节点1的内容</node1>
      <node2 attribute="属性值">NODE CONTENT</node2>
      <中文节点>content of chinese node</中文节点>
    </root>

    6、用XML来做点什么

      6.1、1.xml

    <?xml version="1.0" encoding="GB2312"?>
    <root>
        <My_Program_Code content="1"></My_Program_Code>
    </root>

    7、

    8、

  • 相关阅读:
    SQLyog连接MySQL8.0报2058错误的完美解决方法
    WPF之Binding深入探讨未参考
    C# SQLite 创建数据库的方法增删查改语法和命令
    winform实现INotifyPropertyChanged
    排序算法
    GitHub代码上传
    SQLyog
    Jenkins 部署 .NET MVC 项目
    Visual Studio 2019 代码规范
    C# SqlHelper类
  • 原文地址:https://www.cnblogs.com/cppskill/p/6213572.html
Copyright © 2020-2023  润新知