libxml2库 读取xml文件,写xml文件

原创 2016年08月30日 14:12:15

所用xml文件内容:

<?xml version="1.0" encoding="utf-8"?>
<style name="file">
  <contents name="type">
    <content>.mp3</content>
    <content>.mp4</content>
    <content>.wma</content>
    <content>.mkv</content>
    <content>.avi</content>
  </contents>
  <check>-2852</check>
</style>

XmlReader.h实现功能,得到一个xml文件中的全部内容以及效验xml文件的有效性!


#include <string>
#include <iostream>
#include <stdio.h>
#include <list>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>


class XmlReader
{
public:
    XmlReader();
    ~XmlReader();


    std::list<std::string> getAllContent(std::string filename);
    bool checkXml(std::string filename);

private:
    int checkMethod(const char* content);

private:
    xmlDocPtr m_doc;
    xmlNodePtr m_node;
    xmlChar* m_nodeContent;

};


XmlReader.cpp内容:


#include "XmlReader.h"
#include <cstring>
#include <iostream>


using namespace std;

    XmlReader::XmlReader()
        : m_doc(NULL)
        , m_node(NULL)
        , m_nodeContent(NULL)
    {

    }
    XmlReader::~XmlReader()
    {

    }

    list<string> XmlReader::getAllContent(std::string filename)
    {
        const char *docname = filename.c_str();
        xmlKeepBlanksDefault(0);
        m_doc = xmlParseFile(docname);

        if(m_doc == NULL){
            fprintf(stderr, "Document not parse successfully. \n");
        }

        /* obtain root node */
        m_node = xmlDocGetRootElement(m_doc);
        if(m_node == NULL){
            fprintf(stderr, "empty document\n");
            xmlFreeDoc(m_doc);
        }

        m_node = m_node->xmlChildrenNode;
        m_node = m_node->xmlChildrenNode;

        list<string> fileType;
        char* type;
        while (NULL != m_node) {
            type = (char*)xmlNodeGetContent(m_node);
            string strType(type);
            fileType.push_back(strType);

            m_node = m_node->next;
        }

        return fileType;
    }

bool XmlReader::checkXml(std::string filename)
{
    const char *docname = filename.c_str();
    xmlKeepBlanksDefault(0);
    m_doc = xmlParseFile(docname);

    if(m_doc == NULL){
        fprintf(stderr, "Document not parse successfully. \n");
    }

    /* obtain root node */
    m_node = xmlDocGetRootElement(m_doc);
    if(m_node == NULL){
        fprintf(stderr, "empty document\n");
        xmlFreeDoc(m_doc);
    }

    //read xml file content
    m_node = m_node->xmlChildrenNode;
    m_nodeContent = xmlNodeGetContent(m_node);
    cout << "content:" << m_nodeContent << endl;
    int contentVal = checkMethod((const char*)m_nodeContent);

    //read check content
    while (NULL != m_node->next) {
        m_node = m_node->next;
    }
    m_nodeContent = xmlNodeGetContent(m_node);
    cout << "check val:" << m_nodeContent << endl;
    int checkVal = atoi((const char*)m_nodeContent);

    if (!(contentVal + checkVal)) {
        return true;
    }

    return false;

}

int XmlReader::checkMethod(const char* content)
{
    int length = strlen(content);
    int checkNum = 0;
    for (int i = 0; i < length; ++i)
    {
        /* code */
        checkNum += content[i];
    }

    return checkNum;
}


运行结果:

linux:~/workspace/xml/testxml$ g++ -o testxml.out testxml.cpp XmlReader.cpp -I/usr/include/libxml2/ -lxml2
linux:~/workspace/xml/testxml$ ./testxml.out 
.mp3
.mp4
.wma
.mkv
.avi
content:.mp3.mp4.wma.mkv.avi
check val:-2852
0
linux:~/workspace/xml/testxml$ 


写xml文件:

XmlWriter.h文件。实现功能:
fileTypeWrite函数向xml文件中加入新的节点,然后checkValWrite计算所有contents节点下面的字符的每个字节的和,之后取反。

这里用到的是xmlReadFile读取,而没有用xmlParseFile,因为前者在写入时,可以写入回车字符,在使用xmlSaveFormatFile保存文件时,注意第三个参数设置为1。

#include <string>
#include <iostream>
#include <stdio.h>
#include <list>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>


class XmlWriter
{
public:
    XmlWriter();
    ~XmlWriter();


    void fileTypeWrite(std::string filename,  const char* type);
    bool checkValWrite(std::string filename);

private:
    int checkVal(const char* content);

private:
    xmlDocPtr m_doc;
    xmlNodePtr m_node;
    xmlChar* m_nodeContent;

};

XmlWriter.cpp文件内容:

#include <cstring>
#include <iostream>
#include <stdlib.h>

#include "XmlWriter.h"

using namespace std;

    XmlWriter::XmlWriter()
        : m_doc(NULL)
        , m_node(NULL)
        , m_nodeContent(NULL)
    {

    }

    XmlWriter::~XmlWriter()
    {

    }

    void XmlWriter::fileTypeWrite(std::string filename, const char* type)
    {
        const char *docname = filename.c_str();
        //xmlKeepBlanksDefault(0);
        //m_doc = xmlParseFile(docname);
        m_doc = xmlReadFile(docname, NULL, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);

        if(m_doc == NULL){
            fprintf(stderr, "Document not parse successfully. \n");
        }

        /* obtain root node */
        m_node = xmlDocGetRootElement(m_doc);
        if(m_node == NULL){
            fprintf(stderr, "empty document\n");
            xmlFreeDoc(m_doc);
        }

        m_node = m_node->xmlChildrenNode;

        xmlNodePtr nodePtr = NULL;
        nodePtr = xmlNewTextChild(m_node, NULL, (const xmlChar*)"content", (const xmlChar*)type);
        if (NULL == nodePtr) {
            fprintf(stderr, "add node failed\n");
        }


        if (m_doc != NULL) {
            //xmlSaveFormatFile(filename, doc, 0);
            xmlSaveFormatFile (filename.c_str(), m_doc, 1);
            xmlFreeDoc(m_doc);
        }

    }

bool XmlWriter::checkValWrite(std::string filename)
{
    const char *docname = filename.c_str();
    //xmlKeepBlanksDefault(0);
    //m_doc = xmlParseFile(docname);
    m_doc = xmlReadFile(docname, NULL, XML_PARSE_NOBLANKS | XML_PARSE_NODICT);

    if(m_doc == NULL){
        fprintf(stderr, "Document not parse successfully. \n");
    }

    /* obtain root node */
    m_node = xmlDocGetRootElement(m_doc);
    if(m_node == NULL){
        fprintf(stderr, "empty document\n");
        xmlFreeDoc(m_doc);
    }

    m_node = m_node->xmlChildrenNode;
    // while (NULL != m_node->next) {
    //     m_node = m_node->next;
    // }

    m_nodeContent = xmlNodeGetContent(m_node);
    cout << "content val:" << m_nodeContent << endl;
    int checkValue = -checkVal((const char*)m_nodeContent);
    char* chVal = new char[100];
    sprintf(chVal, "%d", checkValue);


    cout << chVal << endl;


cout << "===========================" << endl;

    m_node = xmlDocGetRootElement(m_doc);

    m_node = m_node->xmlChildrenNode;
    while (NULL != m_node->next) {
        m_node = m_node->next;
    }

    if ((!xmlStrcmp(m_node->name, (const xmlChar *)"check"))) {
        xmlNodeSetContent(m_node, (const xmlChar*)chVal);
    } else {
        m_node = xmlDocGetRootElement(m_doc);
        xmlNodePtr nodePtr = NULL;
        nodePtr = xmlNewTextChild(m_node, NULL, (const xmlChar*)"check", (const xmlChar*)chVal);
        if (NULL == nodePtr) {
            fprintf(stderr, "add check value failed\n");
        }
    }



    delete []chVal;

    if (m_doc != NULL) {
        //xmlSaveFormatFile(docname, doc, 0);
        xmlSaveFormatFile (docname, m_doc, 1);
        xmlFreeDoc(m_doc);
    }

}

int XmlWriter::checkVal(const char* content)
{
    int length = strlen(content);
    int checkNum = 0;
    for (int i = 0; i < length; ++i)
    {
        /* code */
        checkNum += content[i];
    }

    return checkNum;
}


运行结果:

linux:~/workspace/xml/testxml$ g++ -o testxml.out testxml.cpp XmlWriter.cpp -I/usr/include/libxml2/ -lxml2
linux:~/workspace/xml/testxml$ ./testxml.out 
content val:.mp3.mp4.wma.mkv.avi.avi
-2120
===========================
linux:~/workspace/xml/testxml$ 

Write完之后的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<style name="file">
  <contents name="type">
    <content>.mp3</content>
    <content>.mp4</content>
    <content>.wma</content>
    <content>.mkv</content>
    <content>.avi</content>
    <content>.avi</content>
  </contents>
  <check>-2120</check>
</style>















C++中使用libxml2读取xml文件

linux下,纯c++使用libxml2读取xml文件 下载libxml2 [url]ftp://ftp.xmlsoft.org/libxml2/libxml2-sources-2.7.1.tar...
  • yusiguyuan
  • yusiguyuan
  • 2013年10月16日 08:38
  • 2133

libxml读取xml文件的其他方法

在前面一篇文章我提到了一种分析文档的方法,即调用xmlParseFile函数。当我看了libxml官网上的code examples之后,我发现libxml还提供了更加精准的分析方式。 1 ...
  • HDUTigerkin
  • HDUTigerkin
  • 2012年05月08日 17:12
  • 2690

C++读写XML文件(Libxml2库)

C++程序有时候要读写XML文件, 这里介绍一个读写XML文件的库——Libxml2。 主页:http://xmlsoft.org/index.html 入门教程很详细的:http://jianl...
  • tujiaw
  • tujiaw
  • 2011年12月07日 21:47
  • 9335

[libxml2]_[C/C++]_[使用libxml2读取分析xml文件]

场景: 1. xml文件大部分时候都是用来做配置用的, 而windows的msxml库又不是Windows自带的库,使用它得打包, 而且花时间学习这个独立于平台的库不划算. 2. libxml2是跨平...
  • infoworld
  • infoworld
  • 2015年07月20日 09:57
  • 1891

xml文件解析(二)——运用libxml2库解析xml文件

如何解析一个xml文件呢,我们可以使用libxml2库。 libxml2解析xml文件的要点是需要理解xml文档的树形结构,弄懂三个指针root,children及next,其分别代表父、子及同胞关...
  • CODINGCS
  • CODINGCS
  • 2016年02月28日 20:30
  • 474

【C++】使用libxml解析XML文件

OpenCV中使用FileStorage创建和解析XML文件。但FileStorage不能处理节点为空的情况,且对属性也不友好。例子见这里。libxml是C接口的处理xml文件的开源代码库。...
  • xiaowei_cqu
  • xiaowei_cqu
  • 2014年01月22日 11:26
  • 7883

libxml的使用(1)--读取xml

libxml是一个用于解析xml文件的库,在各个平台下都能使用,也支持多种语言,如c,python等。这里是官方网站。上面有libxml的api和一些code examples,都是英文的。不过比较简...
  • HDUTigerkin
  • HDUTigerkin
  • 2012年05月08日 16:47
  • 8629

libxml2如何解析xml格式的字符串

1.     xmlParseMemory,字符串转为XML文档 2.     xmlDocGetRootElement,获取XML文档根节点 3.     xmlStrcmp,比较XML...
  • ai2000ai
  • ai2000ai
  • 2016年06月21日 10:29
  • 1721

libxml2 使用教程

/* 查询节点集 */   xmlXPathObjectPtr getnodeset(xmlDocPtr doc, xmlChar *xpath){       xmlXPathContextPtr ...
  • mcgrady_tracy
  • mcgrady_tracy
  • 2015年06月06日 11:33
  • 2946

libxml2对XML文件的创建、解析、查找、修改

项目中要实现一个管理XML文件的后台程序,需要对XML文件进行创建,解析,修改,查找等操作,下面介绍如何利用libxml2提供的库来实现上述功能。 1、创建XML文档: 我们使用xmlNewDoc()...
  • tracyjk
  • tracyjk
  • 2010年11月11日 13:29
  • 6662
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:libxml2库 读取xml文件,写xml文件
举报原因:
原因补充:

(最多只允许输入30个字)