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

📄 xml.cpp

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

			unsigned long N = 0;
			for(int z = (y - 1) ; z >= 0 ; z--)
				{
				N += dig[z] * XMLHelper :: pow(16,(y - 1) - z);
				}

			// Convert result to UTF-8
			char d1[100] = {0};
#ifdef _WIN32
			wchar_t d2[100] = {0};
			swprintf(d2,L"%c",(wchar_t)N);
			WideCharToMultiByte(CP_UTF8,0,d2,-1,d1,100,0,0);
#endif
			strcat(trg + x,d1);
			x += strlen(d1);
			i++;
			continue;
			}
		if (src[i] == '&' && src[i + 1] == '#')
			{
			i += 2;
			int dig[10] = {0};
			int y = 0;

			while (src[i] >= 0x30 && src[i] <= 0x39)
				{
				dig[y] = src[i] - 0x30;
				y++;
				i++;
				}

			unsigned long N = 0;
			for(int z = (y - 1) ; z >= 0 ; z--)
				{
				N += dig[z] * XMLHelper :: pow(10,(y - 1) - z);
				}

			// Convert result to UTF-8
			char d1[100] = {0};
#ifdef _WIN32
			wchar_t d2[100] = {0};
			swprintf(d2,L"%c",(wchar_t)N);
			WideCharToMultiByte(CP_UTF8,0,d2,-1,d1,100,0,0);
#endif
			strcat(trg + x,d1);
			x += strlen(d1);
			i++;
			continue;
			}


		if (src[i] == '&')
			{
			if (strncmp(src + i + 1,"amp;",4) == 0)
				{
				i += 5;
				trg[x] = '&';
				x++;
				}
			else
				if (strncmp(src + i + 1,"quot;",5) == 0)
					{
					i += 6;
					trg[x] = '\"';
					x++;
					}
				else
					if (strncmp(src + i + 1,"apos;",5) == 0)
						{
						i += 6;
						trg[x] = '\'';
						x++;
						}
					else
						if (strncmp(src + i + 1,"lt;",3) == 0)
							{
							i += 4;
							trg[x] = '<';
							x++;
							}
						else
							if (strncmp(src + i + 1,"gt;",3) == 0)
								{
								i += 4;
								trg[x] = '>';
								x++;
								}
							else
								x++; // ignore invalid symbol
			continue;
			}

		trg[x] = src[i];
		i++;
		x++;
		}

	trg[x] = 0;
	return strlen(trg);
	}


size_t XML :: XMLGetValue(const char* section2,const char* attr2,char* put2,size_t maxlen)
	{
	size_t y1 = XMLEncode(section2,0);
	size_t y2 = XMLEncode(attr2,0);

	Z<char> section(y1 + 10);
	Z<char> attr(y2 + 10);

	XMLEncode(section2,section);
	XMLEncode(attr2,attr);

	if (y1 == 0) // root
		{
		int k = root->FindVariable(attr);
		if (k == -1)
			return 0;

		XMLVariable* v = root->GetVariables()[k];

		size_t Sug = v->GetValue(0);
		Z<char> value(Sug + 10);
		v->GetValue(value);
		size_t Y = strlen(value);
		if (Y > maxlen)
			return Y;

		strcpy(put2,value);
		return Y;
		}



	// section is a\b\c\d...
	XMLElement* r = root;
	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;
		}

	// element with this variable is found !
	int k = r->FindVariable(attr);
	if (k == -1)
		return 0;

	XMLVariable* v = r->GetVariables()[k];

	size_t Sug = v->GetValue(0);
	Z<char> value(Sug + 10);
	v->GetValue(value);
	size_t Y = strlen(value);
	if (Y > maxlen)
		return Y;

	strcpy(put2,value);
	return Y;
	}

void XML :: XMLSetValue(const char* section2,const char* attr,char* put)
	{
	// section is a\b\c\d...
	XMLElement* r = root;
	XMLElement* rr = root;
	Z<char> section(strlen(section2) + 10);
	strcpy(section,section2);
	char* a2 = section.operator char *();

	// Also set to delete values
	// if put is NULL, delete the specified attribute
	// if attr is NULL, delete the specified section (and all subsections!)

	if (!section || strlen(section) == 0)
		{
		int k = root->FindVariable(attr);
		if (k == -1)
			{
			XMLVariable* x = new XMLVariable(attr,"",0);
			root->AddVariable(x);
			k = root->FindVariable(attr);
			}

		if (put == 0)
			{
			// Delete this attribute
			root->RemoveVariable(k);
			}
		else
			{
			root->GetVariables()[k]->SetValue(put);
			}
		return;
		}

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

		y = r->FindElement(a2);
		if (y == -1)
			{
			// Create this element
			XMLElement* n = new XMLElement(r,a2);
			r->AddElement(n);
			y = r->FindElement(n);
			}

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

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

	// element with this variable is found/created!
	if (attr == 0)
		{
		// DELETE this element AND all sub-elements!!
		rr->RemoveElement(y);
		return;
		}


	int k = r->FindVariable(attr);
	if (k == -1)
		{
		XMLVariable* x = new XMLVariable(attr,"",0);
		r->AddVariable(x);
		k = r->FindVariable(attr);
		}


	if (put == 0)
		{
		// Delete this attribute
		r->RemoveVariable(k);
		}
	else
		{
		r->GetVariables()[k]->SetValue(put);
		}
	}




char* XMLHelper :: FindXMLClose(char* s)
	{
	// For Each <!-- we must find a -->
	// For Each <?   we must find a ?>
	// For each <> , we must find a </>
	// For each <![CDATA[ we mst find a ]]>
	// For each < /> , its all ok :)

	int d = 0;
	char* a2 = s;
	bool IsComment = false;
	bool IsCData = false;

	for(;;)
		{
		char* a1 = strchr(a2,'<');
		if (!a1) // duh
			return 0;

		if (*(a1 + 1) == '/')
			{
			a2 = strchr(a1,'>');
			if (!a2) // duh
				return 0; 
			a2++;
			d--;
			if (!d)
				return a2;

			continue;
			}

		if ((*(a1 + 1) == '!' && strlen(a1) > 2 && *(a1 + 2) == '-' && *(a1 + 3) == '-') || *(a1 + 1) == '?')
			IsComment = true;

		if (*(a1 + 1) == '!' && strlen(a1) > 8 && strncmp(a1 + 1,"![CDATA[",8) == 0)
			IsCData = true;

		bool Nest = 0;
		for(;;)
			{
			// Bugfix
			if (IsCData && (*(a1) != ']' || *(a1 + 1) != ']' || *(a1 + 2) != '>'))
				{
				a1++;
				continue;
				}
			if (IsCData)
				{
				a1 += 2;
				break;
				}

			if (*a1 != '/' && *a1 != '>')
				{
				if (*a1 == '\"')
					Nest = !Nest;

				a1++;
				continue;
				}
			if (*a1 == '/' && Nest)
				{
				a1++;
				continue;
				}

			// Also continue if / and no comment/no cdata
			if (*a1 == '/' && (IsComment || IsCData))
				{
				a1++;
				continue;
				}

			// Also continue if > and cdata with no ]]
			if (*a1 == '>' && IsCData && (*(a1 - 1) != ']' || *(a1 - 2) != ']'))
				{
				a1++;
				continue;
				}

			// Also continue if > and comment with no --
			if (*a1 == '>' && IsComment && (*(a1 - 1) != '-' || *(a1 - 2) != '-'))
				{
				a1++;
				continue;
				}


			break;
			}

		d++;


		if ((*a1 == '/' || IsComment) && !IsCData) // nice, it closes
			{
			IsComment = false;
			a2 = a1 + 1;
			d--;
			if (d == 0)
				return a2; // finish !
			continue;
			}

		if (*a1 == '>' && IsCData && *(a1 - 1) == ']' && *(a1 - 2) == ']')
			{
			IsCData = false;
			a2 = a1 + 1;

			d--;
			if (d == 0)
				return a2; // finish !
			continue;
			}

		a2 = a1 + 1;
		}
	}   

void XMLHelper :: AddBlankVariable(XMLElement* parent,char *a2,int Pos)
	{
	size_t Y = strlen(a2);
	if (Y == 0 || parent == 0)
		return;

	char* a1 = a2;
	while(*a1 == ' ' || *a1 == '\t' || *a1 == '\n' || *a1 == '\r')
		a1++;
	size_t Z = strlen(a1);
	if (Z == 0)
		return;
	size_t PZ = Z;

	while(a1[PZ - 1] == '\t' || a1[PZ - 1] == '\r' || a1[PZ - 1] == '\n' || a1[PZ - 1] == ' ')
		PZ--;

	if (PZ == 0)
		return;

	char CC = a1[PZ];
	a1[PZ] = 0;

	// Add this vrb
	XMLContent* x = new XMLContent(parent,Pos,a1,true);
	parent->AddContent(x,Pos);
	a1[PZ] = CC;
	}

XMLElement* XMLHelper :: ParseElementTree(XMLHeader* hdr,XMLElement* parent,char* tree,char** EndValue,XML_PARSE_STATUS& iParseStatus)
	{
	char *a1,*a2,*a3,*a4,*a5;//,*a6;
	char c1,c2;//,c3,c4,c5,c6;

	XMLElement* root = 0;

	bool IsRootCommentSecond = false;

	a2 = tree;
	for(;;)
		{
		// find
		a3 = strchr(a2,'<');
		if (!a3)
			{
			int Pos = parent ? parent->GetChildrenNum() : 0;
			XMLHelper :: AddBlankVariable(parent,a2,Pos);
			break; // end/error
			}


		// Bugfix: See if a3 is cdata
		bool IsCData = false;
		if (strncmp(a3,"<![CDATA[",8) == 0)
			IsCData = true;
		// Bugfix: See if a3 is comment
		bool IsComment = false;
		if (strncmp(a3,"<!--",4) == 0)
			IsComment = true;

		// Between a3 and a2, add everything which isn't \r\n,space,tabs
		*a3 = 0;
		int PosV = parent ? parent->GetChildrenNum() : 0;
		XMLHelper :: AddBlankVariable(parent,a2,PosV);
		*a3 = '<';

		if (IsCData == true)
			a4 = strstr(a3,"]]>");
		else
			if (IsComment == true)
				a4 = strstr(a3,"-->");
			else
				a4 = strchr(a3,'>');
		if (!a4)
			break; // end/error
		if (IsCData)
			a4 += 2; // move to '>'
		if (IsComment)
			a4 += 2; // move to '>'

		if ((*(a3 + 1) == '!' && strlen(a3 + 1) > 2 && *(a3 + 2) == '-' && *(a3 + 3) == '-' ) || *(a3 + 1) == '?') // comment/markup
			{
			c2 = *a4;
			*a4 = 0;
			if (parent)
				{
				//XMLElement* c = new XMLElement(parent,a3 + 1,1);
				//parent->AddElement(c);
				int Pos = parent->GetChildrenNum();
				Z<char> com(strlen(a3) + 100);
				strncpy(com,a3 + 4,strlen(a3 + 4) - 2);
				XMLComment* c = new XMLComment(parent,Pos,com);
				parent->AddComment(c,Pos);
				}
			else // It is a root comment
				{
				int Pos = IsRootCommentSecond;
				Z<char> com(strlen(a3) + 100);
				if (strlen(a3 + 4) > 1)
					strncpy(com,a3 + 4,strlen(a3 + 4) - 2);
				XMLComment* c = new XMLComment(0,Pos,com);
				hdr->AddComment(c,Pos);
				}
			*a4 = c2;
			a2 = a4 + 1;
			continue;
			}

		if ((*(a3 + 1) == '!' && strlen(a3 + 1) > 8 && strncmp(a3 + 1,"![CDATA[",8) == 0)) // cdata
			{
			c2 = *a4;
			*a4 = 0;

			int Pos = parent->GetChildrenNum();
			Z<char> com(strlen(a3) + 100);
			strncpy(com,a3 + 9,strlen(a3 + 9) - 2);
			XMLCData* c = new XMLCData(parent,Pos,com);
			parent->AddCData(c,Pos);

			*a4 = c2;
			a2 = a4 + 1;
			continue;
			}


		if (*(a3 + 1) == '/') // bye bye from this element
			{
			if (parent && root && parent->FindElement(root) == -1)
				parent->AddElement(root);
			a2 = a4 + 1;
			continue;
			}


		IsRootCommentSecond = true;
		// It is an opening element
		// If < /> , all ok, Add to current and continue
		// If < > , then find relative at end, and recursive

		if (*(a4 - 1) == '/')
			{
			// Yes it is this element alone
			c2 = *a4;
			*a4 = 0;
			XMLElement* c = new XMLElement(parent,a3 + 1,0);
			if (parent)
				parent->AddElement(c);
			else
				;// invalid. Can't have a < /> root

			*a4 = c2;
			a2 = a4 + 1;
			if (!root)
				root = c;
			continue;
			}



		// Now it is an < > entry
		// Find this one at end, strchr <
		a5 = XMLHelper :: FindXMLClose(a3);
		if (!a5)
			{
			// ERROR in the FILE
			iParseStatus = XML_PARSE_ERROR;
			return root;
			}

		a5--; // fixes a bug when next element is rightly after closing
		while(*a5 != '<')
			a5--;
		a1 = a5;
		c1 = *a1;
		*a1 = 0;

		// Create element a3
		c2 = *(a4 + 1);
		*(a4 + 1) = 0;
		root = new XMLElement(parent,a3,0);
		*(a4 + 1) = c2;
		char* eV = 0;
		XMLHelper :: ParseElementTree(hdr,root,a4 + 1,&eV,iParseStatus);



		char* sa2 = a2;
		*a1 = c1;
		a2 = a1;
		if (eV)
			a2 = eV;
		if (a2 == sa2)
			break; // whops ? error! . Break to avoid fatal loop
		continue;
		}

	return root;
	}

int XMLElement :: RemoveAllElements()
	{
	for(int i = childrennum - 1 ; i >= 0 ; i--)
		{
		if (children[i] == 0)
			{
			// Unload 
			DeleteUnloadedElementFile(i);
			}

		bool DoDelete = true;
		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;
		}
	childrennum = 0;
	return 0;
	}

void XMLElement :: SetElementParam(unsigned __int64 p)
	{
	param = p;
	}

unsigned __int64 XMLElement :: GetElementParam()
	{
	return param;
	}


int XMLElement :: DeleteUnloadedElementFile(int i)
	{
	// 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");

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

⌨️ 快捷键说明

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