当前位置:早雪网网络学院编程文档其他语言 → 写了一个简单的处理类似xml文件的类,请大家指正【原创】

写了一个简单的处理类似xml文件的类,请大家指正【原创】

减小字体 增大字体 作者:未知  来源:supcode.com收集整理  发布时间:2005-7-1 14:53:22

说明:只是个菜鸟,贴出来的目的是希望有大侠指点一下,不足之处,c++学习时间不长,呵。或者帮忙测试一下,共同完善之。

头文件:

//=========================================================
//
// Copyright (c) 2000-2005 TT Technologies,Co. Ltd.
// All Rights Reserved.
//
// Class: CTTXmlFile
//
// Product: TTLibrary
// File   : TTXmlFile.h
// Author : http://blog.csdn.net/waterpub
// Created: 2005.03.07 11:30
//  
// Description:
//     ValueAdded main program for TTLibrary.
//                   Contact:ShenZhen @ GuangDong
//                       waterpub@mail.csdn.net
//
//========================================================= 
#pragma once 
#include
			"string" 
#include
			"vector" 
#include
			"utility" 
#include
			"algorithm" 
using
			namespace std;

namespace TTLibrary
{
	// 维护一个xml条目的类
	class CTTXmlItem
	{
	public:
		CTTXmlItem(const string& sItemName);
		~CTTXmlItem();
		inline
			bool SetKeyValue(const string& sKey, const string& sValue);
		inline
			bool SetKeyValue(const string& sKey, const
			int& nValue);
		inline
			bool GetKeyValueString(const string& sKey, string& sValue) const;
		inline
			bool GetKeyValueInt(const string& sKey, int& nValue) const;
		inline
			bool MergeAnother(const CTTXmlItem& xi);
		inline string GetItemName() const{ return m_sItemName; }
#ifdef _DEBUG 
		void Debug();
#endif 

	private:
		const vector<pair<string, string> >* GetKeyVector() const;

	private:
		string m_sItemName;							// 条目名
		vector<pair<string, string> > m_KeyVector;	// 该条目下的键值列表
		friend
			class CTTXmlFile;

	private:
		class CTTXmlItemFind						// 查找键值的仿函数
		{
		public:
			CTTXmlItemFind(const string& sKey)
			{
				m_sKey = sKey;
			}
			bool
			operator() (const pair<string, string>& XmlItemData)
			{
				if (XmlItemData.first == m_sKey) 
				{
					return
			true;
				}
				else
				{
					return
			false;
				}
			}
		private:
			string	m_sKey;
		};
	};

	// 加载xml并解析的类
	class CTTXmlFile
	{
	public:
		CTTXmlFile(void);
		~CTTXmlFile(void);

	public:
		bool clear();
		bool Load(const string& sFileName);
		bool Save(const string& sFileName =
			"");
		bool AddItem(const CTTXmlItem& xi);
		bool RemoveItem(const string& sItemName);
#ifdef _DEBUG 
		void Debug();
#endif 

	private:
		bool ParseItem(char* &pStr);
		bool ParseKey(char* &pStr, CTTXmlItem& xi);
		bool SkipBlank(char* &pStr);
		bool SkipEqualChar(char* &pStr);
		bool FindWord(char* &pStr, string& sWord);

	private:
		string				m_sFileName;	// 加载的文件名
		vector<CTTXmlItem>	m_ItemVector;	// 条目列表

	private:
		class CTTXmlItemFind				// 查找xml条目列表中有否相同名字的条目的仿函数
		{
		public:
			CTTXmlItemFind(const string& sItemName)
			{
				m_sItemName = sItemName;
			}
			bool
			operator() (const CTTXmlItem& xi)
			{
				if (xi.GetItemName() == m_sItemName) 
				{
					return
			true;
				}
				else
				{
					return
			false;
				}
			}

		private:
			string	m_sItemName;
		};
	};
}





实现文件:

			
#include
					"StdAfx.h" 
#include
					"ttxmlfile.h" 

namespace TTLibrary
{
	CTTXmlItem::CTTXmlItem(const string& sItemName)
	{
		m_sItemName = sItemName;
	}

	CTTXmlItem::~CTTXmlItem()
	{
	}

	bool CTTXmlItem::SetKeyValue(const string& sKey, const string& sValue)
	{
		vector<pair<string, string> >::iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			(*it).second = sValue;
		}
		else
		{
			pair<string, string> XmlItemData;
			XmlItemData.first = sKey;
			XmlItemData.second = sValue;
			m_KeyVector.push_back(XmlItemData);
		}

		return
					true;
	}

	bool CTTXmlItem::SetKeyValue(const string& sKey, const
					int& nValue)
	{
		string sValue;
		char szValue[26];
		itoa(nValue, szValue, 10);
		sValue = szValue;
		SetKeyValue(sKey, sValue);
		return
					true;
	}

	bool CTTXmlItem::GetKeyValueString(const string& sKey, string& sValue) const
	{
		vector<pair<string, string> >::const_iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			sValue = (*it).second;
			return
					true;
		}
		else
		{
			return
					false;
		}
	}

	bool CTTXmlItem::GetKeyValueInt(const string& sKey, int& nValue) const
	{
		vector<pair<string, string> >::const_iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			nValue = atoi((*it).second.c_str());
			return
					true;
		}
		else
		{
			return
					false;
		}
	}

	const vector<pair<string, string> >* CTTXmlItem::GetKeyVector() const
	{
		return &m_KeyVector;
	}

	bool CTTXmlItem::MergeAnother(const CTTXmlItem& xi)
	{
		if (xi.GetItemName() == m_sItemName)
		{
			vector<pair<string, string> >::const_iterator it = (xi.GetKeyVector())->begin();
			for(; it != (xi.GetKeyVector())->end(); it++)
			{
				SetKeyValue((*it).first, (*it).second);
			}
		}

		return
					true;
	}

#ifdef _DEBUG 
	void CTTXmlItem::Debug()
	{
		XTRACE("     ===========================\n");
		XTRACE(RGB(0, 0, 255), "     条目名:%s\n", m_sItemName.c_str());
		vector<pair<string, string> >::iterator it = m_KeyVector.begin();
		for(; it != m_KeyVector.end(); it++)
		{
			XTRACE("     键:%s,值:%s\n", (*it).first.c_str(), (*it).second.c_str());
		}
	}
#endif 

	CTTXmlFile::CTTXmlFile(void)
	{
	}

	CTTXmlFile::~CTTXmlFile(void)
	{
	}

	bool CTTXmlFile::AddItem(const CTTXmlItem& xi)
	{
		vector<CTTXmlItem>::iterator it = find_if(m_ItemVector.begin(), m_ItemVector.end(), 
			CTTXmlItemFind(xi.GetItemName()) );
		if (it != m_ItemVector.end()) 
		{
			(*it).MergeAnother(xi);
			return
					false;
		}
		else
		{
			// 没有此条目则添加
			m_ItemVector.push_back(xi);
			return
					true;
		}
	}

	bool CTTXmlFile::RemoveItem(const string& sItemName)
	{
		vector<CTTXmlItem>::iterator it = find_if(m_ItemVector.begin(), m_ItemVector.end(), 
			CTTXmlItemFind(sItemName) );
		if (it != m_ItemVector.end()) 
		{
			// 有此条目则删除
			m_ItemVector.erase(it);
			return
					true;
		}
		else
		{
			return
					false;
		}
	}

	bool CTTXmlFile::clear()
	{
		m_ItemVector.clear();
		m_sFileName.clear();

		return
					true;
	}

	bool CTTXmlFile::Load(const string& sFileName)
	{
		if (sFileName.empty()) return
					false;
		char szDirBuf[MAX_PATH] =
					"";
		GetCurrentDirectory(MAX_PATH, szDirBuf);
		strncat(szDirBuf, "\\", strlen("\\"));
		strncat(szDirBuf, sFileName.c_str(), sFileName.size());

		clear();
		m_sFileName = szDirBuf;
		FILE* hFile = fopen(m_sFileName.c_str(), "r");
		if (NULL == hFile) return
					false;

		string strText;
		char* szBuf =
					new
					char[1024
					+
					1];

		while (!feof(hFile))
		{
			int nRead = (int)fread(szBuf, 1, 1024, hFile);
			if (nRead > 0) 
			{
				szBuf[nRead] = NULL;
				strText += szBuf;
			}
		}
		fclose(hFile);

		char* pStr = (char*)strText.c_str();
		// 解析文件
		while (pStr != NULL) 
		{
			if(!ParseItem(pStr)) break;
		}

#ifdef _DEBUG 
		Debug();
#endif 

		delete []szBuf;
		return
					true;
	}

	bool CTTXmlFile::Save(const string& sFileName)
	{
		return
					true;
	}

	// 从文件中解析出一个条目
	bool CTTXmlFile::ParseItem(char* &pStr)
	{
		char* pStart = pStr;
		while (*pStart !=
					'<' && *pStart != NULL) 
			pStart++;

		if (*pStart == NULL)
		{
			pStr = pStart;
			return
					false;	// 解析文件结束
		}
		else
		{
			pStart++;		// 从'<'后面开始
			SkipBlank(pStart);

			// 解析条目名
			string sItemName;
			if(FindWord(pStart, sItemName))
			{
				CTTXmlItem xi(sItemName);

				// 解析键值
				ParseKey(pStart, xi);
#ifdef _DEBUG 
				//			xi.Debug();
#endif 
				m_ItemVector.push_back(xi);
			}
			// 消除对应的'>'字符
			SkipBlank(pStart);
			if (*pStart ==
					'>') pStart++; 
			pStr = pStart;

			return
					true;
		}

	}

	bool CTTXmlFile::ParseKey(char* &pStr, CTTXmlItem& xi)
	{
		string sKey;
		string sValue;
		while (FindWord(pStr, sKey)) 
		{
			if( SkipEqualChar(pStr))
			{
				if( FindWord(pStr, sValue))
				{
					xi.SetKeyValue(sKey, sValue);
				}
			}
		}
		SkipBlank(pStr);

		return
					true;
	}

	bool CTTXmlFile::SkipBlank(char* &pStr)
	{
		while ((*pStr > 0 && *pStr < 33))
			pStr++;

		return
					true;
	}

	bool CTTXmlFile::SkipEqualChar(char* &pStr)
	{
		SkipBlank(pStr);
		if (*pStr ==
					'=')
		{
			pStr++;
			return
					true;
		}
		else
			return
					false;
	}

	// 字符串,不能为 '<' 或 '>' 或 '='
	bool CTTXmlFile::FindWord(char* &pStr, string& sWord)
	{
		SkipBlank(pStr);
		char* pStart = pStr;
		while ((*pStart >=
					33
					|| *pStart < 0) && *pStart !=
					'<' && *pStart != '>' && *pStart !=
					'=')
			pStart++;

		if (pStart == pStr)
		{
			pStr = pStart;
			return
					false;
		}
		else
		{
			string strTemp(pStr, pStart);
			sWord = strTemp;

			pStr = pStart;
			return
					true;
		}

	}

#ifdef _DEBUG 
	void CTTXmlFile::Debug()
	{
		XTRACE("***********************************************\n");
		XTRACE(RGB(255, 0, 0), "文件名:%s\n", m_sFileName.c_str());
		XTRACE("***********************************************\n");
		vector<CTTXmlItem>::iterator it = m_ItemVector.begin();
		for(; it!= m_ItemVector.end(); it++)
		{
			(*it).Debug();
		}
	}
#endif 
}


测试文件:test.ini,如下(写的很乱,作为加强测试,):
fdsafd
fdsafds
< ><aaaaa=sfd
< >>
< aa>fdsafds
< tt aaa = bbb  >
< test >
<name Name1=ccc name2 = ddd> 测试代码:  CTTXmlFile ttxf;
 ttxf.Load("skin2.ini");

Tags:简单,处理,类似,xml,文件,指正,原创
[数据载入中...] [返回上一页] [打 印]