1.实现功能:读取一个xml文件中的内容,节点等信息!

首先定义了一个test.xml文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<story name="test">
        <content name = "lsp">
                <pro id="moonApple"><![CDATA[<say>i still have lots to work on</say>]]></pro>
                <details>
                        <detail name="dancing">like it</detail>
                        <detail name="singing">poor , just listen</detail>
                        <detail name="laugh"/>
                        <detail name="eating"><![CDATA[<food>candy</food>]]></detail>
                </details>
        </content>
</story>

写了三个文件:分别为:testxml.cpp     ReadXml.cpp     ReadXml.h

testxml.cpp内容如下:

#include "ReadXml.h"
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <string>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{

    //string filename = "parser.xml";
    string filename = "usb.xml";

    ReadXml rx;
    const char* name = (char*)rx.getRootNodeName(filename);
    cout << name << endl;

    const char* content = (char*)rx.getAllContent(filename);
    cout << content << endl;




    xmlDocPtr doc = NULL;
    xmlNodePtr cur = NULL;
    xmlChar* szKey;

    const char *docname = filename.c_str();
    xmlKeepBlanksDefault(0);
    doc = xmlParseFile(docname);
    if(doc == NULL){
        fprintf(stderr, "Document not parse successfully. \n");
        return 0;
    }

    /* obtain root node */
    cur = xmlDocGetRootElement(doc);



    if(cur == NULL){
        fprintf(stderr, "empty document\n");
        xmlFreeDoc(doc);
        return 0;
    }

    cur = cur->xmlChildrenNode;
    //cout << "attributes is :" <<xmlGetProp(cur, (const xmlChar*)"name") << endl;
    cout << "attributes is :" <<rx.getNodeAttributes(cur, (const xmlChar*)"name") << endl << endl;

    const char* nodecontent = (char*)rx.getNodeContent(cur);
    cout << nodecontent << endl;

    cur = cur->next;
    const char* nodeattribute = (char*)rx.getNodeAttributes(cur,  (const xmlChar*)"attributes");
    if (NULL == nodeattribute) {
        cout << "nodeattribute is null!" << endl;
    } else {
        cout << "nodeattribute is:" << nodeattribute << endl;
    }

    //cout << xmlGetProp(cur, (const xmlChar*)"name") << endl;
    return 1;
}

解析:

testxml.cpp文件中,定义了main函数,主要就是调用自定义的实现读取xml功能的ReadXml类,然后测试在该类中定义的一些函数。下面解释一下该文件中用到的一些函数的意思。

首先:

xmlDocPtr doc = NULL;  
xmlNodePtr node = NULL;  
doc = xmlParseFile(filename); 

xmlDocPtr 表示指向xmlDoc的指针。xmlDoc是一个包含了已解析的文件生成的节点树的结构体。

xmlDocGetRootElement(doc)可以得到整个文件的根节点,所有的操作都是从根节点开始的。

xmlGetProp可以得到节点属性,第一个参数为节点,第二个参数为节点名称。返回xmlChar类型!

节点包含这么几个信息:

node->name:节点的名字,如node1,node2,subnode等

node->xmlChildrenNode:节点的子节点

node->last:节点的最后一个子节点

node->parent:节点的父节点

node->next:节点的兄弟节点,对于node1来说,node2和node3都是其兄弟节点,node1的next指向node2

由于节点的内容是其子节点(对于node1,content1可以说是其子节点),所以我们需要使用xmlNodeGetContent来取出内容。



如果出现读取信息不正确的情况,请看这里::

libxml默认将各个节点间的空格当作一个节点,只要在调用xmlParseFile之前调用xmlKeepBlanksDefault(0)即可!


ReadXml.cpp内容如下:

#include <iostream>

#include "ReadXml.h"

using namespace std;

    ReadXml::ReadXml()
    {

    }
    ReadXml::~ReadXml()
    {

    }

    const xmlChar* ReadXml::getRootNodeName(std::string filename)
    {
        const char *docname = filename.c_str();
        xmlKeepBlanksDefault(0);
        doc = xmlParseFile(docname);
        if(doc == NULL){
            fprintf(stderr, "Document not parse successfully. \n");
            return 0;
        }

        /* obtain root node */
        cur = xmlDocGetRootElement(doc);
        if(cur == NULL){
            fprintf(stderr, "empty document\n");
            xmlFreeDoc(doc);
            return 0;
        }

        return cur->name;
        //printf("root node :%s\n", cur->name);
        //szKey = xmlNodeGetContent(cur);
        //printf("all content:\n %s \n", szKey);

    }

    xmlChar* ReadXml::getAllContent(std::string filename)
    {
        const char *docname = filename.c_str();
        xmlKeepBlanksDefault(0);
        doc = xmlParseFile(docname);
        if(doc == NULL){
            fprintf(stderr, "Document not parse successfully. \n");
            return 0;
        }

        /* obtain root node */
        cur = xmlDocGetRootElement(doc);
        if(cur == NULL){
            fprintf(stderr, "empty document\n");
            xmlFreeDoc(doc);
            return 0;
        }

        szKey = xmlNodeGetContent(cur);
        return szKey;
    }

    xmlChar* ReadXml::getNodeContent(xmlNodePtr node)
    {
        return xmlNodeGetContent(node);
    }

    xmlChar* ReadXml::getNodeAttributes(xmlNodePtr node, const xmlChar * name)
    {
        return xmlGetProp(node, name);
        //rerutn value should free use xmlFree(szAttr);
    }




ReadXml.h内容如下:

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

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

    const xmlChar* getRootNodeName(std::string filename);
    xmlChar* getAllContent(std::string filename);
    xmlChar* getNodeContent(xmlNodePtr cur);
    xmlChar* getNodeAttributes(xmlNodePtr node, const xmlChar * name);

private:
    xmlDocPtr doc;
    xmlNodePtr cur;
    xmlChar* szKey;

};

编译代码为:

g++ -o testxml.out testxml.cpp ReadXml.cpp -I/usr/include/libxml2/ -lxml2
./testxml.out 

执行结果为:

lsp@liushuanpeng:~/gccConfig$ ./testxml.out 
story
<say>i still have lots to work on</say>like itpoor , just listen<food>candy</food>
attributes is :lsp

<say>i still have lots to work on</say>like itpoor , just listen<food>candy</food>
nodeattribute is null!


参考链接:













Logo

更多推荐