加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

libxml2解析XML

发布时间:2020-12-16 05:14:10 所属栏目:百科 来源:网络整理
导读:最近需要在Linux下解析Xml,原来用的msxml排不上用场了,就自己封装了一下libxml2,当然易用性比不上msxml,凑活能用,呵呵,嗯,记录一下吧,先看.h文件 #ifndef __DOXML_H__#define __DOXML_H__#include libxml/parser.h#include iconv.h#include stringusi

最近需要在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解析的类。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读