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

📄 xml.cpp

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

int XMLElement :: RemoveElement(unsigned int i)
	{
	if (i >= childrennum)
		return childrennum;

	if (children[i] == 0)
		{
		// Unloaded already, just delete the file
		DeleteUnloadedElementFile(i);
		}

	bool DoDelete = true;
	// Check if this item is borrowed
	for(unsigned int xi = 0 ; xi < NumBorrowedElements ; xi++)
		{
		if (BorrowedElements[xi].Active == 0)
			continue;
		if (BorrowedElements[xi].x == children[i])
			{
			BorrowedElements[xi].Active = 0;
			DoDelete = false;
			break;
			}
		}


	if (DoDelete)
		delete children[i];

	children[i] = 0;

	for(unsigned int k = i ; k < childrennum ; k++)
		children[k] = children[k + 1];

	children[childrennum - 1] = 0;
	return --childrennum;
	}

int XMLElement :: RemoveElementAndKeep(unsigned int i,XMLElement** el)
	{
	if (el) 
		*el = 0;   

	if (i >= childrennum)
		return childrennum;

	if (children[i] == 0) // unloaded
		ReloadElement(i);

	//delete children[i];
	if (el) 
		*el = children[i];   
	children[i] = 0;

	for(unsigned int k = i ; k < childrennum ; k++)
		children[k] = children[k + 1];

	children[childrennum - 1] = 0;
	return --childrennum;
	}

int XMLElement :: UnloadElement(unsigned int i)
	{
	XMLElement* e = children[i];
	if (!e)
		return 1; // already unloaded

	e->ReloadAllElements();

	// Find Unique STR
	size_t si = GetElementUniqueString(0);
	Z<char> us(si);
	GetElementUniqueString(us);
	if (us[strlen(us) - 1] == '-')
		us[strlen(us) - 1] = 0;
	// Add this element
	if (strlen(us))
		sprintf(us + strlen(us),"-%u",i);
	else
		sprintf(us + strlen(us),"%u",i);
	// Extension
	strcat(us,".xmltmp");



	FILE* fp = fopen(us,"rb");
	if (fp)
		{
		// file exists !
		fclose(fp);
		return 0;
		}

	fp = fopen(us,"wb");
	if (!fp)
		{
		// Failed !
		return 0;
		}

	e->Export(fp,1,XML_SAVE_MODE_ZERO);
	fclose(fp);

	// Delete this element, but do not remove it.
	delete children[i];
	children[i] = 0;

	return 1;
	}

int XMLElement :: ReloadElement(unsigned int i)
	{
	if (children[i])
		return 1; // Item is already here

	// Find Unique STR
	size_t si = GetElementUniqueString(0);
	Z<char> us(si);
	GetElementUniqueString(us);
	if (us[strlen(us) - 1] == '-')
		us[strlen(us) - 1] = 0;
	// Add this element
	if (strlen(us))
		sprintf(us + strlen(us),"-%u",i);
	else
		sprintf(us + strlen(us),"%u",i);
	// Extension
	strcat(us,".xmltmp");

	FILE* fp = fopen(us,"rb");
	if (!fp)
		{
		// file failed !
		return 0;
		}
	fclose(fp);
	XML fx(us);
	int K = fx.ParseStatus();
	if (K == 2) // Fatal error
		return 0; 

	XMLElement* r = fx.RemoveRootElementAndKeep();

	// Reload element
	children[i] = r;
	r->SetParent(this);

#ifdef LINUX
	remove(us);
#else // Win32
#ifdef WINCE // Only Wide
	Z<wchar_t> usw(si + 1000);
	MultiByteToWideChar(CP_ACP,0,us,-1,usw,si + 1000);
	DeleteFileW(usw);
#else
	DeleteFileA(us);
#endif
#endif
	return 1;
	}

int XMLElement :: ReloadAllElements()
	{
	for(unsigned int i = 0 ; i < childrennum ; i++)
		{
		if (children[i] == 0)
			ReloadElement(i);
		}

	return 0;
	}


int XMLElement :: MoveElement(unsigned int i,unsigned int y)
	{
	if (i >= childrennum || y >= childrennum)
		return childrennum;

	XMLElement* x = children[i];

	children[i] = 0;
	for(unsigned int k = i ; k < childrennum ; k++)
		children[k] = children[k + 1];

	childrennum--;
	return InsertElement(y,x);
	}

int XMLElement :: InsertElement(unsigned int y,XMLElement* x)
	{
	// leave from 0 to y
	// move from y + 1 to childrennum + 1
	// save
	// childrennum++;
	if (y >= childrennum)
		return AddElement(x);

	SpaceForElement(1);

	memmove((void*)(children + y + 1),(void*)(children + y),(childrennum - y)*sizeof(XMLElement*));
	children[y] = x;
	x->SetParent(this);
	childrennum++;
	return y;
	}

int XMLElement :: BorrowElement(XMLElement*x,unsigned int y)
	{
	// Same as Insert or Add, but no SetParent

	// put 'x' in the list of 'borrowed elements'
	if (BorrowedElements.is() <= NumBorrowedElements)
		BorrowedElements.AddResize(5);
	XMLBORROWELEMENT xb = {0};
	xb.Active = 1;
	xb.x = x;
	BorrowedElements[NumBorrowedElements++] = xb;

	SpaceForElement(1);
	if (y >= childrennum)
		{
		children[childrennum++] = x;
		return childrennum;
		}

	memmove((void*)(children + y + 1),(void*)(children + y),(childrennum - y)*sizeof(XMLElement*));
	children[y] = x;
	childrennum++;

	return y;
	}

int XMLElement :: ReleaseBorrowedElements()
	{
	int R = 0;
	for(unsigned int y = 0 ; y < NumBorrowedElements ; y++)
		{
		XMLBORROWELEMENT& xb = BorrowedElements[y];
		if (xb.Active == 0)
			continue;
		for(int i = (childrennum - 1) ; i >= 0 ; i--)
			{
			if (children[i] == xb.x)
				{
				RemoveElement(i);
				xb.Active = 0;
				R++;
				}
			}
		}
	NumBorrowedElements = 0;
	return R;
	}

int XMLElement :: UpdateElement(XMLElement* e,bool UpdateVariableValues)
	{
	/*

	Formula

	Checks variables, if not existing, copies
	If existing, does nothing.
	Search is case-sensitive.

	Checks elements, if not existing, copies
	if existing, calls UpdateElement() for each element

	*/

	// Test the variables
	Z<char> vn(1000);
	for(unsigned int i = 0 ; i < e->GetVariableNum() ; i++)
		{
		XMLVariable* v = e->GetVariables()[i];
		if (v->GetName(0) > 1000)
			vn.Resize(v->GetName(0) + 1000);
		v->GetName(vn);

		XMLVariable* tv = FindVariableZ(vn,0);
		if (tv == 0)
			{
			// Create
			AddVariable(v->Duplicate());
			}
		else
			{
			if (UpdateVariableValues)
				{
				if (v->GetValue(0) > 1000)
					vn.Resize(v->GetValue(0) + 1000);
				v->GetValue(vn);
				tv->SetValue(vn);
				}
			}
		}

	// Test the elements
	for(unsigned int i = 0 ; i < e->GetChildrenNum() ; i++)
		{
		XMLElement* c = e->GetChildren()[i];
		if (c->GetElementName(0) > 1000)
			vn.Resize(c->GetElementName(0) + 1000);
		c->GetElementName(vn);

		XMLElement* tc = FindElementZ(vn,0);
		if (tc == 0)
			{
			// Copy
			AddElement(c->Duplicate());
			}
		else
			{
			tc->UpdateElement(c,UpdateVariableValues);
			}
		}




	return 0;
	}

int XMLElement :: RemoveTemporalVariables(bool Deep)
	{
	int iNum = 0;
	for(int i = variablesnum - 1 ; i >= 0 ; i--)
		{
		if (variables[i]->IsTemporal())
			{
			RemoveVariable(i);
			iNum++;
			}
		}
	if (Deep)
		{
		for(unsigned int i = 0 ; i < childrennum ; i++)
			{
			iNum += children[i]->RemoveTemporalVariables();
			}
		}
	return iNum;
	}

int XMLElement :: RemoveTemporalElements(bool Deep)
	{
	int iNum = 0;
	for(int i = childrennum - 1 ; i >= 0 ; i--)
		{
		if (children[i]->IsTemporal())
			{
			RemoveElement(i);
			iNum++;
			}
		}
	if (Deep)
		{
		for(unsigned int i = 0 ; i < childrennum ; i++)
			{
			iNum += children[i]->RemoveTemporalElements();
			}	
		}
	return iNum;
	}

int XMLElement :: RemoveAllVariables()
	{
	for(int i = variablesnum - 1 ; i >= 0 ; i--)
		{
		delete variables[i];
		variables[i] = 0;
		}
	variablesnum = 0;
	return 0;
	}


int XMLElement :: RemoveVariable(unsigned int i)
	{
	if (i >= variablesnum)
		return variablesnum;

	delete variables[i];
	variables[i] = 0;

	for(unsigned int k = i ; k < variablesnum ; k++)
		variables[k] = variables[k + 1];

	variables[variablesnum - 1] = 0;
	return --variablesnum;
	}

int XMLElement :: RemoveVariableAndKeep(unsigned int i,XMLVariable** vr)
	{
	if (vr) 
		{
		*vr = 0;   
		}
	if (i >= variablesnum)
		return variablesnum;

	//delete variables[i];
	if (vr) 
		{
		*vr = variables[i];   
		}
	variables[i] = 0;

	for(unsigned int k = i ; k < variablesnum ; k++)
		variables[k] = variables[k + 1];

	variables[variablesnum - 1] = 0;
	return --variablesnum;
	}

void XML :: Export(FILE* fp,XML_SAVE_MODE SaveMode,XML_TARGET_MODE TargetMode,XMLHeader *hdr,class XMLTransform* eclass,class XMLTransformData* edata)
	{
	// Export all elements
	root->Export(fp,1,SaveMode,TargetMode,hdr,eclass,edata);
	}

void XML :: SetExportFormatting(XMLEXPORTFORMAT* xf)
	{
	root->SetExportFormatting(xf);
	}

XMLElement* XMLElement :: GetElementInSection(const char* section2)
	{
	// From section, get the element we need
	XMLElement* r = this;
	if (strcmp(section2,"") == 0)
		return this;

	Z<char> section(strlen(section2) + 1);
	strcpy(section,section2);

	char* a2 = section.operator char *();

	for( ; ; )
		{
		char* a1 = strchr(a2,'\\');
		if (a1)
			*a1 = 0;

		int y = r->FindElement(a2);
		if (y == -1)
			{
			if (a1)
				*a1 = '\\';
			return 0;
			}

		r = r->GetChildren()[y];
		if (!a1) // was last
			break;

		*a1 = '\\';
		a2 = a1 + 1;
		}


	return r;
	}


void XMLElement :: Write16String(FILE* fp,const char* s)
	{
#ifdef _WIN32
	size_t sl = strlen(s)*2 + 100;
	Z<wchar_t> ws(sl);
	MultiByteToWideChar(CP_UTF8,0,s,-1,ws,(int)sl);
	fwrite(ws.operator wchar_t*(),1,wcslen(ws)*2,fp);
#endif
	}

void XMLElement :: printc(FILE* fp,XMLElement* root,int deep,int ShowAll,XML_SAVE_MODE SaveMode,XML_TARGET_MODE TargetMode)
	{
	if (!root)
		return;

	root->ReloadAllElements();

	char* sp = (char*)fp;
	if (TargetMode == 1)
		sp += strlen(sp);
	unsigned int spi = 0;
#ifdef _WIN32
	HKEY pKey = (HKEY)fp;
	HKEY pKey2 = 0;
#endif


	/*
	Targetmodes

	0 	- Export to a FILE*
	1 	- Export to memory
	2  - Export to a registry key (Win32)
	3  - Export to a FILE* , utf-16

	*/

	char DelimiterChar[100] = {0};
	if (root->xfformat.UseSpace)
		{
		for(int i = 0 ; i < root->xfformat.nId ; i++)
			strcat(DelimiterChar," ");
		}
	else
		{
		for(int i = 0 ; i < root->xfformat.nId ; i++)
			strcat(DelimiterChar,"\t");
		}
	//* Use it later


	size_t Sug = root->GetElementName(0,SaveMode);
	Z<char> b(Sug + deep + 100);
	for(int i = 0 ; i < deep ; i++)
		//strcat(b,"\t");
		strcat(b,DelimiterChar);

	strcat(b,"<");
	root->GetElementName(b.operator char*() + strlen(b),SaveMode);
	if (TargetMode == 1)
		{
		spi = sprintf(sp,"%s",b.operator char*());
		sp += spi;
		}
	else
		if (TargetMode == 2)
			{
#ifdef _WIN32
#ifndef WINCE
			XMLElement* par = root->GetParent();
			int bP = 0;
			if (par)
				{
				bP = par->FindElement(root);
				}
			sprintf(b,"E%u",bP);
			root->GetElementName(b.operator char *() + strlen(b),SaveMode);
			DWORD dw = 0;
			RegCreateKeyExA(pKey,b,0,0,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,0,&pKey2,&dw);
#endif
#endif
			}
		else
			if (TargetMode == 3)
				Write16String(fp,b.operator char*());
			else
				fprintf(fp,"%s",b.operator char*());

	int iY = root->GetVariableNum();
	int iC = root->GetChildrenNum();

	// print variables if they exist
	//   XMLVariable* SaveAstVariable = 0;
	if (iY)
		{
		for(int i = 0 ; i < iY ; i++)
		 {
		 XMLVariable* v = root->GetVariables()[i];
		 size_t s1 = v->GetName(0,SaveMode);
		 size_t s2 = v->GetValue(0,SaveMode);

		 Z<char> Name(s1 + 10);
		 Z<char> Value(s2 + 10);

		 v->GetName(Name,SaveMode);
		 v->GetValue(Value,SaveMode);

		 /*		 if (strcmp(Name,"*") == 0)
		 SaveAstVariable = v;
		 else*/
			 {
			 if (TargetMode == 1)
				 {
				 spi = sprintf(sp," %s=",Name.operator char*());
				 sp += spi;
				 spi = sprintf(sp,"\"%s\"",Value.operator char*());
				 sp += spi;
				 }
			 else
				 if (TargetMode == 2)
					 {
#ifdef _WIN32
#ifndef WINCE
					 // create a value
					 Z<char> VName(strlen(Name) + 10);
					 sprintf(VName,"V%s",Name.operator char*());
					 RegSetValueExA(pKey2,VName,0,REG_SZ,(const BYTE*)Value.operator char *(),(int)(strlen(Value) + 1));
#endif
#endif
					 }
				 else
					 if (TargetMode == 3)
						 {
						 Z<char> xy(strlen(Name)*2 + 100 + strlen(Value)*2);
						 sprintf(xy," %s=\"%s\"",Name.operator char*(),Value.operator char*());
						 Write16String(fp,xy);
						 }
					 else // TM == 0
						 {
						 fprintf(fp," %s=",Name.operator char*());
						 fprintf(fp,"\"%s\"",Value.operator char*());
						 }
			 }
		 }
		}

	// cdatas, comments, contents may be between children
	int TotalCDatas = root->GetCDatasNum();
	int NextCData = 0;

	int TotalComments = root->GetCommentsNum();
	int NextComment = 0;

	int TotalContents = root->GetContentsNum();
	int NextContent = 0;

	// children ?
	// close now if no children/contents/comments
	if ((!iC || ShowAll == 0) && /*SaveAstVariable == 0 &&*/ TotalContents == 0 && TotalComments == 0 && TotalCDatas == 0)
		{
		if (TargetMode == 1)
			{
			spi = sprintf(sp,"/>\r\n");
			sp += spi;
			}
		else
			if (TargetMode == 2)
				; // Nothing :)
			else
				if (TargetMode == 3)
					fwrite(L"/>\r\n",1,4,fp);
				else // 0
					fprintf(fp,"/>\r\n");
		return;
		}
	if (TargetMode == 1)
		{
		spi = sprintf(sp,">\r\n",b.operator char*());
		sp += spi;
		}
	else
		{
		// Write \r\n only if ElementBreak
		if (root->xfformat.ElementsNoBreak == false || TotalContents != 1 || TotalComments || TotalCDatas || iC)
			{
			if (TargetMode == 2)
				; // Nothing :)
			else
				if (TargetMode == 3)
					fwrite(L">\r\n",1,3,fp);
				else
					fprintf(fp,">\r\n",b.operator char*());
			}
		else
			{

⌨️ 快捷键说明

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