⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.cpp

📁 功能齐全的XML解析/生成类. 可以在Windows/WindowsCE下使用.亲自调试通过.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// xml.cpp
#include "stdafx.h"

#ifdef XML_USE_NAMESPACE
namespace XMLPP
	{
#endif

#ifdef USE_EXTERNAL_Z
#include "z.h"
#endif

#include "xml.h"


#ifdef __WATCOMC__
#define _atoi64(x) atoll(x)
#endif


#ifndef __SYMBIAN32__
#ifndef LINUX
#pragma comment(lib,"wininet.lib")
#endif
#endif

//#pragma warning (disable:4244)
//#pragma warning (disable:4267)
//#pragma warning (disable:4800)
#pragma warning (disable:4996)

#ifdef LINUX
#define strcmpi(a,b) strcmp(a,b)
#endif

#ifdef WINCE
#define strcmpi(a,b) strcmp(a,b)
#endif


#ifndef XML_MAX_INIT_CHILDREN
#define XML_MAX_INIT_CHILDREN 20
#endif

#ifndef XML_MAX_INIT_VARIABLES
#define XML_MAX_INIT_VARIABLES 20
#endif

#ifndef XML_MAX_INIT_CONTENTS
#define XML_MAX_INIT_CONTENTS 4
#endif

#ifndef XML_MAX_INIT_COMMENTS
#define XML_MAX_INIT_COMMENTS 10
#endif

#ifndef XML_MAX_INIT_CDATAS
#define XML_MAX_INIT_CDATAS 10
#endif

#ifndef XML_MAX_INIT_COMMENTS_HEADER
#define XML_MAX_INIT_COMMENTS_HEADER 5
#endif

// Help functions    
#define MATCH_TRUE 1
#define MATCH_FALSE 0
#define MATCH_ABORT -1

#define NEGATE_CLASS
#define OPTIMIZE_JUST_STAR
#undef MATCH_TAR_PATTERN

// OPTI

/* Extra definitions

XML_OPTIONAL_WIN32
XML_OPTIONAL_IMPORTDB
XML_OPTIONAL_MIME
XML_OPTIONAL_IMPORTRKEY
*/

#ifdef XML_OPTIONAL_MIME
#include "mime.h"
#endif

int XML :: DoMatch(const char *text, char *p, bool IsCaseSensitive)
	{
	// probably the MOST DIFFICULT FUNCTION in TurboIRC
	// Thanks to BitchX for copying this function
	//int last;
	int matched;
	//int reverse;
	int pT = 0;
	int pP = 0;

	for(; p[pP] != '\0'; pP++, pT++)
		{
		if (text[pT] == '\0' && p[pP] != '*')
			return MATCH_ABORT;
		switch (p[pP])
			{
			//         case '\\': // Match with following char
			//                pP++;
			// NO BREAK HERE

			default:
				if (IsCaseSensitive)
					{
					if (text[pT] != p[pP])
						return MATCH_FALSE;
					else
						continue;
					}
				if (toupper(text[pT]) != toupper(p[pP]))
					//         if (DMtable[text[pT]] != DMtable[p[pP]])
					return MATCH_FALSE;
				continue;

			case '?':
				continue;

			case '*':
				if (p[pP] == '*')
					pP++;
				if (p[pP] == '\0')
					return MATCH_TRUE;
				while (text[pT])
					{
					matched = DoMatch(text + pT++, p + pP);
					if (matched != MATCH_FALSE)
						return matched;
					}
				return MATCH_ABORT;

			}
		}
#ifdef MATCH_TAR_PATTERN
	if (text[pT] == '/')
		return MATCH_TRUE;
#endif
	return (text[pT] == '\0');
	}



// This will be called from the other funcs
bool XML :: VMatching(const char *text, char *p, bool IsCaseSensitive)
	{
#ifdef OPTIMIZE_JUST_STAR
	if (p[0] == '*' && p[1] == '\0')
		return MATCH_TRUE;
#endif
	return (DoMatch(text, p, IsCaseSensitive) == MATCH_TRUE);
	}




// XML class

void XML :: Version(XML_VERSION_INFO* x)
	{
	x->VersionLow = (XML_VERSION & 0xFF);
	x->VersionHigh = (XML_VERSION >> 8);
	strcpy(x->RDate,XML_VERSION_REVISION_DATE);
	}

XML :: XML()
	{
	Init();
	IsFileU = false;
	}

void XML :: SetUnicode(bool x)
	{
	IsFileU = x;
	}

XML :: XML(const char* file,XML_LOAD_MODE LoadMode,class XMLTransform* eclass,class XMLTransformData* edata)
	{
	Init();
	Load(file,LoadMode,eclass,edata);
	}

#ifndef LINUX
XML :: XML(const wchar_t* file,XML_LOAD_MODE LoadMode,class XMLTransform* eclass,class XMLTransformData* edata)
	{
	Init();
	Load((char*)file,XML_LOAD_MODE_LOCAL_FILE_U,eclass,edata);
	}
#endif


size_t XML :: LoadText(const char* txt)
	{
	return Load(txt,XML_LOAD_MODE_MEMORY_BUFFER,0,0);
	}

size_t XML :: LoadText(const wchar_t* txt)
	{
#ifdef _WIN32
	size_t udsize = wcslen(txt);
	size_t dsize = udsize*4 + 1000; // just for safety
	Z<char> utfbuff(dsize);

	// Conver the array
	WideCharToMultiByte(CP_UTF8,0,txt,-1,utfbuff,(int)dsize,0,0);
	return LoadText(utfbuff);
#else
	return 0;
#endif
	}

void XML :: Init()
	{
	SOnClose = 0;
	hdr = 0;
	root = 0;
	f = 0;
	}

void XML :: Clear()
	{
	if (SOnClose)
		Save();
	// root
	if (root)
		{
		root->RemoveAllElements();
		delete root;
		}
	root = 0;

	// hdr
	if (hdr)
		delete hdr;
	hdr = 0;

	// item
	if (f)
		delete[] f;
	f = 0;
	}


XMLElement* XML :: GetRootElement()
	{
	return root;
	}

void XML :: Lock(bool)
	{

	}

void XML :: SetRootElement(XMLElement* newroot)
	{
	delete root;
	root = 0;
	root = newroot;
	return;
	}

XMLElement* XML :: RemoveRootElementAndKeep()
	{
	XMLElement* x = root;
	root = new XMLElement(0,"<root/>");
	return x;
	}

int XML :: RemoveTemporalElements()
	{
	if (!root)
		return 0;

	int iN = 0;
	iN += root->RemoveTemporalElements(true);
	iN += root->RemoveTemporalVariables(true);
	return iN;
	}






XMLHeader* XML :: GetHeader()
	{
	return hdr;
	}

void XML :: SetHeader(XMLHeader* h)
	{
	if (hdr)
		delete hdr;
	hdr = 0;
	hdr = h;
	}

size_t XML :: XMLEncode(const char* src,char* trg)
	{
	if (!src)
		return 0;
	//*...
	size_t Y = strlen(src);

	size_t x = 0;
	for(size_t i = 0 ; i < Y ; i++)
		{
		if (src[i] == '&' && src[i + 1] != '#')
			{
			if (trg)
				strcat(trg + x,"&amp;");
			x += 5;
			continue;
			}
		if (src[i] == '>')
			{
			if (trg)
				strcat(trg + x,"&gt;");
			x += 4;
			continue;
			}
		if (src[i] == '<')
			{
			if (trg)
				strcat(trg + x,"&lt;");
			x += 4;
			continue;
			}
		if (src[i] == '\"')
			{
			if (trg)
				strcat(trg + x,"&quot;");
			x += 6;
			continue;
			}
		if (src[i] == '\'')
			{
			if (trg)
				strcat(trg + x,"&apos;");
			x += 6;
			continue;
			}

		if (trg)
			trg[x] = src[i];
		x++;
		}
	if (trg)
		trg[x] = 0;
	return x;
	}

#ifdef XML_OPTIONAL_IMPORTRKEY

XMLElement* XML :: ImportRKey(IMPORTRKEYDATA* d)
	{
	HKEY pK = d->pK;
	int mode = d->StorageType;

	XMLElement* x = new XMLElement(0,"<root />");

	// Reads pK (Assumes it is open) and imports ALL children !

	// if mode == 0 , native backup
	// no name prefix, variable B,I,Y,E,Z,N,Q,S
	//

	// Reads Values of pK and writes it to myself
	for(int i = 0 ; ; i++)
		{
		Z<char> tmp1(300);
		DWORD ts = 20000;
		DWORD ty = 0;
		DWORD si = 0;
		RegEnumValue(pK,i,tmp1,&ts,0,&ty,0,&si);
		Z<char> tmp2(si + 10);

		ts = 20000;
		if (RegEnumValue(pK,i,tmp1,&ts,0,&ty,(unsigned char*)tmp2.operator char *() + 2,&si) != ERROR_SUCCESS)
			break; // end of values

		// write
		if (ty == REG_BINARY)
			tmp2[0] = 'B';
		if (ty == REG_DWORD)
			tmp2[0] = 'I';
		if (ty == REG_DWORD_BIG_ENDIAN)
			tmp2[0] = 'Y';
		if (ty == REG_EXPAND_SZ)
			tmp2[0] = 'E';
		if (ty == REG_MULTI_SZ)
			tmp2[0] = 'Z';
		if (ty == REG_NONE)
			tmp2[0] = 'N';
		if (ty == REG_QWORD)
			tmp2[0] = 'Q';
		if (ty == REG_SZ)
			tmp2[0] = 'S';

		if (mode == 0)
			tmp2[1] = '_';

		XMLVariable* v = new XMLVariable(tmp1,tmp2);
		x->AddVariable(v);
		}

	// Now enum children keys and do the same
	for(int i = 0 ; ; i++)
		{
		Z<char> tmp1(300);
		Z<char> tmp2(300);
		DWORD si = 300;

		if (RegEnumKeyEx(pK,i,tmp1,&si,0,0,0,0) != ERROR_SUCCESS)
			break; // end of values

		sprintf(tmp2,"<%s />",tmp1.operator char*());
		XMLElement* child = new XMLElement(x,tmp2);


		HKEY NewPK = 0;
		RegOpenKeyEx(pK,tmp1,0,KEY_ALL_ACCESS,&NewPK);
		if (NewPK)
			{
			IMPORTRKEYDATA d2 = {0};
			d2.pK = NewPK;
			d2.StorageType = mode;
			ImportRKey(&d2);
			x->AddElement(child);
			RegCloseKey(NewPK);
			}
		}

	return x;
	}
#endif


#ifdef XML_OPTIONAL_IMPORTDB
#include <exdisp.h>
#include <urlmon.h>
#include <shlobj.h>
//#include <adoid.h>
#include <adoint.h>

#define ADOGUID(name, l) extern "C" const GUID name = \
	{l, 0, 0x10, 0x80,0,0,0xAA,0,0x6D,0x2E,0xA4}
ADOGUID(CLSID_CADOConnection,0x00000514);
ADOGUID(IID_IADOConnection,0x00000550);

XMLElement* XML :: ImportDB(IMPORTDBPARAMS* db)
	{
	// Imports an MDB database with ADO
	XMLElement* r = 0;
	Z<char> str(1000);
	Z<wchar_t> wstr(1000);

	ADOConnection* aC = 0;
	HRESULT hr;
	BSTR b1 = 0,b2 = 0,b3 = 0;

	// Open Database
	CoCreateInstance(CLSID_CADOConnection,0,CLSCTX_ALL,IID_IADOConnection,(void**)&aC);
	if (!aC)
		goto E_0;

	if (db->provstr == 0)
		sprintf(str,"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s",db->dbname);
	else
		sprintf(str,db->provstr,db->dbname);

	MultiByteToWideChar(CP_ACP,0,str,-1,wstr,1000);


	b1 = SysAllocString(L"");
	b2 = SysAllocString(L"");
	b3 = SysAllocString(wstr);
	hr = aC->Open(b3,b1,b2,0);
	SysFreeString(b1);
	SysFreeString(b2);
	SysFreeString(b3);

	if (hr)
		goto E_1;

	r = new XMLElement(0,"<db />");

	// Loop for all tables
	for(int iTable = 0 ; iTable < db->nTables ; iTable++)
		{
		ADORecordset* aR = 0;
		VARIANT* RecordsAffected = 0;

		sprintf(str,"SELECT * FROM %s",db->Tables[iTable].name);
		MultiByteToWideChar(CP_ACP,0,str,-1,wstr,1000);
		b1 = SysAllocString(wstr);
		hr = aC->Execute(b1,RecordsAffected,0,&aR);
		SysFreeString(b1);

		if (hr)
			continue;

		// Add this table to r
		sprintf(str,"<%s />",db->Tables[iTable].name);
		XMLElement* rT = new XMLElement(r,str);
		r->AddElement(rT);

		aR->MoveFirst();
		long TotalRecords = 0;
		aR->get_RecordCount(&TotalRecords);

		for(unsigned int y = 0 ; y < (unsigned)TotalRecords ; y++)
			{
			// We are looping the items now
			short IsEOF;
			aR->get_EOF(&IsEOF);
			if (IsEOF == VARIANT_TRUE)
				break;


			long RecordCount = 0;
			ADOFields* aFS = 0;
			aR->get_Fields(&aFS);
			aFS->get_Count(&RecordCount);

			// Add this item
			sprintf(str,"<%s />",db->Tables[iTable].itemname);
			XMLElement* rItem = new XMLElement(rT,str);
			rT->AddElement(rItem);

			for(int iVariables = 0 ; iVariables < RecordCount ; iVariables++)
				{
				// We are loopting the variables now, get only what we actually need
				ADOField* aF = 0;
				VARIANT vt;
				vt.vt= VT_I4;
				vt.intVal = iVariables;

				aFS->get_Item(vt,&aF);
				if (!aF)
					continue;

				wchar_t* Name;
				aF->get_Name(&Name);

				VARIANT Value;
				aF->get_Value(&Value);

				if (Value.vt == VT_BSTR)
					WideCharToMultiByte(CP_UTF8, 0, Value.bstrVal, -1, str, 1000,0,0);
				else
					if (Value.vt == VT_I4)
						sprintf(str,"%u",Value.lVal);

				// Should we add this variable to the rItem ?
				int SL = wcslen(Name);
				Z<char> nam(SL*2 + 100);
				WideCharToMultiByte(CP_UTF8, 0, Name, -1, nam, SL*2 + 100,0,0);
				int IsToAdd = -1;
				for(int yAdds = 0; yAdds < db->Tables[iTable].nVariables ; yAdds++)
					{
					if (strcmpi(db->Tables[iTable].Variables[yAdds],nam) == 0)
						{
						IsToAdd = yAdds;
						break;
						}
					}
				if (IsToAdd != -1)
					{
					char* thename = nam;
					if (db->Tables[iTable].ReplaceVariables[IsToAdd])
						thename = db->Tables[iTable].ReplaceVariables[IsToAdd];
					XMLVariable* var = new XMLVariable(thename,str);
					rItem->AddVariable(var);
					}


				if (Name)
					SysFreeString(Name);
				if (Value.vt == VT_BSTR)
					SysFreeString(Value.bstrVal);
				aF->Release();
				}

			aFS->Release();
			aR->MoveNext();
			}
		}

E_1:
	aC->Release();

E_0:
	return r;
	}
#endif


int XMLHelper :: pow(int P,int z)
	{
	if (z == 0)
		return 1;
	int x = P;
	for(int i = 1 ; i < z ; i++)
		x*= P;
	return x;
	}

size_t XML :: XMLDecode(const char* src,char* trg)
	{
	size_t Y = strlen(src);
	if (!trg)
		return Y;

	size_t x = 0;
	for(size_t i = 0 ; i < Y ; )
		{
		char* fo = strchr((char*)src + i,'&');
		if (!fo)
			{
			// end of &s
			strcpy(trg + x,src + i);
			x = strlen(trg);
			break;
			}

		if (fo)
			{
			size_t untilfo = fo - (src + i);
			strncpy(trg + x,src + i,untilfo);
			i += untilfo;
			x += untilfo;
			}

		if (src[i] == '&' && src[i + 1] == '#' && tolower(src[i + 2]) == 'x')
			{
			i += 3;
			int dig[10] = {0};
			int y = 0;

			while ((src[i] >= 0x30 && src[i] <= 0x39) || (src[i] >= 'a' && src[i] <= 'f') || (src[i] >= 'A' && src[i] <= 'F'))
				{
				char C = src[i];
				if (C >= 0x30 && C <= 0x39)
					C -= 0x30;
				else
					if (C >= 0x41 && C <= 0x46)
						C -= 55;
					else
						if (C >= 0x61 && C <= 0x66)
							C -= 87;

				dig[y] = C;
				y++;
				i++;
				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -