linux下使用libxml2庫,解析xml檔案
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!
參考連結: