最近需要在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,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 &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,size); strncpy(*outxml,inxml,size+1); //xmlDocDumpFormatMemory(doc,&size,0); } xmlNodePtr DoLibXML2::GetNode(xmlNodePtr parent,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解析的类。