• XML_CPP_资料_libXml2_01_Code_ZC(?.pro)


    ZC:最下面有 ?.pro文件的设置写法

    ZC: Win7x64,qt-opensource-windows-x86-msvc2010_opengl-5.3.2.exe,cn_visual_studio_2010_ultimate_x86_dvd_532347.iso

    ZC: 需要和 编译出来的exe放在同一个目录的3个DLL为:iconv.dll、libxml2.dll、zlib1.dll (在下载的libXml2里面有这3个文件)(这一点需要注意 ! ! 不然编译出来的exe在Debug时会报错,而且 从报错的现象上看 也看不出是∵少了这3个DLL...很蛋疼)

    1、

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <libxml/parser.h>
    #include <libxml/tree.h>
    #include <libxml/xpath.h>
    #include "iconv.h"
    
    #include <QDebug>
    #include <QTextCodec>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    
    void MainWindow::on_pbtnParseEncodeError_clicked()
    {
        // ZC: VS2010不管cpp文件的编码 将字符串常亮用Ansi编码,并且 xmlParseMemory默认使用UTF8编码操作,于是 就会报编码的错误。
        // ZC: 可以看到 libXML2 的错误信息,是通过console打印出来的
        char buf[] ="<?xml version="1.0" encoding="UTF-8"?> <JMSB> <HEAD> <CLJG>中过</CLJG> " 
            "<JLTS>recordNo</JLTS>"
            "<CCXX></CCXX>"
            "</HEAD>"
            "</JMSB>";
        xmlDocPtr doc = xmlParseMemory((char*)buf, strlen(buf) + 1);
        xmlFreeDoc(doc);//xmlGenericError xmlSetGenericErrorFunc
    }
    
    // ZC: 创建xml文档
    void MainWindow::on_pbtnTest01_clicked()
    {
        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)
        {
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            //QTextCodec *codec = QTextCodec::codecForName("UTF-8");
            QString str01 = codec->toUnicode("一个xml文档被创建,写入");
            QString str02 = codec->toUnicode("个字节");
            qDebug() << str01 + QString::number(nRel) + str02;
            //qDebug() << "一个xml文档被创建,写入" << nRel << "个字节";
        }
    
        //释放文档内节点动态申请的内存
    
        xmlFreeDoc(doc);
    }
    
    // ZC: 解析xml文档
    void MainWindow::on_pbtnParserXML_clicked()
    {
        xmlDocPtr doc;           //定义解析文档指针
        xmlNodePtr curNode;      //定义结点指针(你需要它为了在各个结点间移动)
        xmlChar *szKey;          //临时字符串变量
    
        char *szDocName = "CreatedXml.xml";
        doc = xmlReadFile(szDocName, "GB2312", XML_PARSE_RECOVER); //解析文件
    
        //检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。
        //一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。
        //如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中.
    
        if (NULL == doc)
        {
            qDebug() << "Document not parsed successfully.";
            return;
        }
    
        curNode = xmlDocGetRootElement(doc); //确定文档根元素
    
        /*检查确认当前文档中包含内容*/
        if (NULL == curNode)
        {
            qDebug() << "Empty document";
            xmlFreeDoc(doc);
            return;
        }
    
        /*在这个例子中,我们需要确认文档是正确的类型。“root”是在这个示例中使用文档的根类型。*/
        if (xmlStrcmp(curNode->name, BAD_CAST "root"))
        {
            qDebug() << "document of the wrong type, root node != root";
            xmlFreeDoc(doc);
            return;
        }
    
        curNode = curNode->xmlChildrenNode;
        xmlNodePtr propNodePtr = curNode;
        while(curNode != NULL)
        {
            //取出节点中的内容
            if ((!xmlStrcmp(curNode->name, (const xmlChar *)"newNode1")))
            {
                szKey = xmlNodeGetContent(curNode);
                qDebug() << "newNode1: " << 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");
                qDebug() << "get attribute = " << szAttr;
                xmlFree(szAttr);
            }
            attrPtr = attrPtr->next;
        }
    
        xmlFreeDoc(doc);
    }
    
    // ZC: 修改xml文档
    void MainWindow::on_pbtnModifyXML_clicked()
    {
        xmlDocPtr doc;   //定义解析文档指针
        xmlNodePtr curNode;  //定义结点指针(你需要它为了在各个结点间移动)
    
        char *szDocName = "CreatedXml.xml";
    
        doc = xmlReadFile(szDocName, "GB2312", XML_PARSE_RECOVER);  //解析文件
    
        if (NULL == doc)
        {
            fprintf(stderr,"Document not parsed successfully. 
    ");
            return;
        }
    
        curNode = xmlDocGetRootElement(doc);
        /*检查确认当前文档中包含内容*/
        if (NULL == curNode)
        {
            fprintf(stderr,"empty document
    ");
            xmlFreeDoc(doc);
            return;
        }
    
        curNode = curNode->children;
        while (NULL != curNode)
        {
            //删除newNode1
            if (!xmlStrcmp(curNode->name, BAD_CAST "newNode1"))
            {
                xmlNodePtr tempNode;
                tempNode = curNode->next;
                xmlUnlinkNode(curNode); // ZC: 解除link
                xmlFreeNode(curNode);   // ZC: 释放内存
                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)
        {
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            QString str01 = codec->toUnicode("一个xml文档被创建,写入");
            QString str02 = codec->toUnicode("个字节");
    
            qDebug() << str01 +QString::number(nRel) + str02;
        }
        xmlFreeDoc(doc);
    }
    
    
    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;
    }
    
    void MainWindow::on_pbtnXPATH_clicked()
    {
        xmlDocPtr doc = NULL;             //定义解析文档指针
        xmlNodePtr curNode = NULL;         //定义结点指针(你需要它为了在各个结点间移动)
    
        char *szDocName = "CreatedXml.xml";
    
        doc = xmlReadFile(szDocName, "GB2312", XML_PARSE_RECOVER);  //解析文件
    
        if (NULL == doc)
        {
            fprintf(stderr,"Document not parsed successfully. 
    ");
            return;
        }
    
        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;
        }
        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);
    }
    
    
    
    //代码转换:从一种编码转为另一种编码
    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;
    }
    
    void MainWindow::on_pbtnZhongWen_clicked()
    {
        //定义文档和节点指针
        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)
        {
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            QString str01 = codec->toUnicode("一个xml文档被创建,写入");
            QString str02 = codec->toUnicode("个字节");
    
            qDebug() << str01 + QString::number(nRel) + str02;
        }
    
        xmlFreeDoc(doc);
    }

    2、界面

    3、"libxml2_z.pro" (公司的笔记本,"F:Z_Qt5Qt532_vs2010libxml2_z")

    4、

    #-------------------------------------------------
    #
    # Project created by QtCreator 2016-12-21T15:02:53
    #
    #-------------------------------------------------
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = libxml2_z
    TEMPLATE = app
    
    
    SOURCES += main.cpp
            mainwindow.cpp
    
    HEADERS  += mainwindow.h
    
    FORMS    += mainwindow.ui
    
    INCLUDEPATH +=  F:C_IDEVC_3rdlibxml2iconv-1.9.2.win32include  
                    F:C_IDEVC_3rdlibxml2libxml2-2.6.30.win32include   
                    F:C_IDEVC_3rdlibxml2zlib-1.2.3.win32include
    
    LIBPATH += F:/ZC_IDE/VC_3rd/libxml2/iconv-1.9.2.win32/lib    
            F:/ZC_IDE/VC_3rd/libxml2/libxml2-2.6.30.win32/lib    
            F:/ZC_IDE/VC_3rd/libxml2/zlib-1.2.3.win32/lib
    
    LIBS += -liconv    
            -llibxml2    
            -lzlib
    #ZC: (1)设置libxml2的头文件目录 (2)设置libxml2的lib文件的目录 (3)指明lib文件 (4)将dll文件复制到exe所在目录(或system32)

    5、

    6、

  • 相关阅读:
    文章评论:级数中达朗贝尔判别法和柯西判别法之间的关系研究 By 彭军
    解析函数论 Page 22 达朗贝尔判别法 VS 柯西判别法
    解析函數論 Page 28 連續復變函數的最簡單的性質
    #2066:一个人的旅行(Dijkstra算法入门题)
    #2072 单词数(字符串流使用)
    传统的DOM渲染方式 吴小明
    【闭包】closure 吴小明
    报文 吴小明
    节流和防抖 吴小明
    什么是模块化?它有什么好处?常用的模块化开发的方案 吴小明
  • 原文地址:https://www.cnblogs.com/cppskill/p/6213824.html
Copyright © 2020-2023  润新知