最近需要在Linux下解析Xml,原来用的msxml排不上用场了,就自己封装了一下libxml2,当然易用性比不上msxml,凑活能用,呵呵,嗯,记录一下吧,先看.h文件
#ifndef __DOXML_H__
#define __DOXML_H__
#include <libxml/parser.h>
#include <iconv.h>
#include <string>
using namespace std;
class DoLibXML2
{
private:
//定义文档和根节点指针
xmlNodePtr root_node,curNode;
xmlDocPtr doc;
public:
DoLibXML2(const string &rootName);
virtual ~DoLibXML2(void);
xmlNodePtr AddNode( const string &name, const string &value );
xmlNodePtr AddNode( xmlNodePtr parent, const string &name, const string &value,
const string &Attribu, const string &AttribuValue );
xmlNodePtr AddTextNode(const string &name, const string &value);
int SaveXMLToFile(const string &sFileName);
int LoadXMLFromFile(const string &sFileName);
void GetXMLString(char **outxml);
int LoadXMLFromString(const string &sXML);
xmlNodePtr GetNode(xmlNodePtr parent, const string &name, string &value);
};
#endif
需要iconv库进行UTF8编码转换,网上可以下载。
再看实现:
#include "stdafx.h"
#include "DoLibXML2.h"
#include <string.h>
DoLibXML2::DoLibXML2(const string &rootName)
{
if (!rootName.empty())
{
doc = xmlNewDoc(BAD_CAST"1.0");
root_node = xmlNewNode(NULL,BAD_CAST rootName.c_str());
//设置根节点
xmlDocSetRootElement(doc,root_node);
}
}
DoLibXML2::~DoLibXML2(void)
{
xmlFreeDoc(doc);
}
xmlNodePtr DoLibXML2::AddTextNode(const string &name, const string &value)
{
xmlNodePtr nd = xmlNewTextChild(root_node, NULL, BAD_CAST name.c_str(), BAD_CAST value.c_str());
return nd;
}
xmlNodePtr DoLibXML2::AddNode(const string &name, const string &value)
{
string AttribuName ;
string AttribuValue ;
xmlNodePtr nd = AddNode(root_node, name, value, AttribuName, AttribuValue);
return nd;
}
xmlNodePtr DoLibXML2::AddNode(xmlNodePtr parent, const string &name, const string &value, const string &AttribuName,
const string &AttribuValue)
{
xmlNodePtr nd = xmlNewNode(NULL, BAD_CAST name.c_str());
if (parent == NULL) {
xmlAddChild(root_node,nd);
}
else {
xmlAddChild(parent,nd);
}
if (!value.empty())
{
xmlAddChild(nd, xmlNewText(BAD_CAST value.c_str()));
}
if (!AttribuName.empty())
{
xmlNewProp(nd,BAD_CAST AttribuName.c_str(),BAD_CAST AttribuValue.c_str());
}
return nd;
}
int DoLibXML2::SaveXMLToFile(const string &sFileName)
{
int nRel = xmlSaveFile(sFileName.c_str(),doc);
//xmlSaveFormatFileEnc
return nRel;
}
int DoLibXML2::LoadXMLFromString(const string &sXML)
{
int len = sXML.length();
doc = xmlParseMemory(sXML.c_str(),len);
root_node = xmlDocGetRootElement(doc); //确定文档根元素
if (NULL == root_node)
{
//xmlFreeDoc(doc);
return -1;
}
return 1;
}
int DoLibXML2::LoadXMLFromFile(const string &sFileName)
{
doc = xmlReadFile(sFileName.c_str(), "GB2312", XML_PARSE_RECOVER); //解析文件
//检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。
//一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。
//如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中.
if (NULL == doc)
{
return -1;
}
root_node = xmlDocGetRootElement(doc); //确定文档根元素
if (NULL == root_node)
{
//xmlFreeDoc(doc);
return -1;
}
return 1;
}
void DoLibXML2::GetXMLString(char **outxml)
{
int size;
char *inxml;
xmlDocDumpMemory( doc, (xmlChar **)&inxml,& size);
*outxml = new char[size+1];
memset(*outxml, 0 , size);
strncpy(*outxml,inxml,size+1);
//xmlDocDumpFormatMemory(doc,(xmlChar **)&inxml, &size,0);
}
xmlNodePtr DoLibXML2::GetNode(xmlNodePtr parent, const string &name, string &value)
{
xmlChar *szKey; //临时字符串变量
if (parent == NULL) {
//保证root不为空
if (NULL == root_node)
{
return NULL;
}
curNode = root_node->xmlChildrenNode;
xmlNodePtr propNodePtr = curNode;
while(curNode != NULL)
{
//取出节点中的内容
if ((!xmlStrcmp(curNode->name, (const xmlChar *)name.c_str())))
{
szKey = xmlNodeGetContent(curNode);
value = (char *)(szKey);
xmlFree(szKey);
propNodePtr = curNode;
return propNodePtr;
}
curNode = curNode->next;
}
return NULL;
}
else {
curNode = parent->xmlChildrenNode;
xmlNodePtr propNodePtr = curNode;
while(curNode != NULL)
{
//取出节点中的内容
if ((!xmlStrcmp(curNode->name, (const xmlChar *)name.c_str())))
{
szKey = xmlNodeGetContent(curNode);
value = (char *)(szKey);
xmlFree(szKey);
propNodePtr = curNode;
return propNodePtr;
}
curNode = curNode->next;
}
return NULL;
}
}
这样就简单封装了一下xml解析的类。