Example #1
0
bool FileProcess::CreateIniXML(std::string strFile)
{
	std::cout << strFile << std::endl;
	// 打开excel
	MiniExcelReader::ExcelFile* x = new MiniExcelReader::ExcelFile();
	if (!x->open(strFile.c_str()))
	{
		printf("can't open %s\n", strFile.c_str());
		return false;
	}
	////////////////////////////////////////////////////////////////////////////
	// 开始创建xml
	tinyxml2::XMLDocument* iniDoc = new tinyxml2::XMLDocument();
	if (NULL == iniDoc)
	{
		return false;
	}
	//xml声明
	tinyxml2::XMLDeclaration *pDel = iniDoc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
	if (NULL == pDel)
	{
		return false;
	}

	iniDoc->LinkEndChild(pDel);

	// 写入XML root标签
	tinyxml2::XMLElement* root = iniDoc->NewElement("XML");
	iniDoc->LinkEndChild(root);

	// 读取excel中每一个sheet
	std::vector<MiniExcelReader::Sheet>& sheets = x->sheets();
	std::vector<std::string> vColNames;
	std::vector<std::string> vDataIDs;
	std::map<std::string, std::string> mDataValues;
	int nCurrentCol = 0;

	for (MiniExcelReader::Sheet& sh : sheets)
	{
		std::string strSheetName = sh.getName();

		std::string strUpperSheetName = strSheetName.substr(0, 8);
		transform(strUpperSheetName.begin(), strUpperSheetName.end(), strUpperSheetName.begin(), ::tolower);

		if (strUpperSheetName != "property")
		{
			continue;
		}

		const MiniExcelReader::Range& dim = sh.getDimension();

		for (int c = dim.firstCol; c <= dim.lastCol; c++)
		{
			MiniExcelReader::Cell* cell = sh.getCell(dim.firstRow, c);
			if (cell)
			{
				vColNames.push_back(cell->value);
			}
		}

		if (vDataIDs.size() <= 0)
		{
			for (int r = dim.firstRow + 8; r <= dim.lastRow; r++)
			{
				MiniExcelReader::Cell* cell = sh.getCell(r, dim.firstCol);
				if (cell)
				{
					if (cell->value.length() > 0)
					{
						vDataIDs.push_back(cell->value);
					}
				}
			}
		}

		for (int r = dim.firstRow + 8; r <= vDataIDs.size() + 8; r++)
		{
			std::string testValue = "";
			MiniExcelReader::Cell* cell = sh.getCell(r, dim.firstCol);

			for (int c = dim.firstCol; c <= dim.lastCol; c++)
			{
				std::string name = vColNames[c - 1 + nCurrentCol];
				std::string value = "";
				MiniExcelReader::Cell* cell = sh.getCell(r, c);
				std::string vType = sh.getCell(dim.firstRow + 1, c)->value;
				if (cell)
				{
					std::string valueCell = cell->value;
					transform(valueCell.begin(), valueCell.end(), valueCell.begin(), ::toupper);
					if (valueCell == "TRUE" || valueCell == "FALSE")
					{
						value = valueCell == "TRUE" ? 1 : 0;
					}
					else
					{
						value = cell->value;
						if (value.size() <= 0)
						{
							if (vType == "int" || vType == "float")
							{
								value = "0";
							}
							else
							{
								value = "";
							}
						}
					}
				}
				else
				{
					if (vType == "int" || vType == "float")
					{
						value = "0";
					}
					else
					{
						value = "";
					}
				}
				//check the field is utf8, then convert it into gbk.
				auto descLength = value.size();
				if (bConvertIntoUTF8 && IsTextUTF8(value.c_str(), descLength))
				{
					if (descLength > 0)
					{
						char* chrArrDesc = new char[descLength];
						Utf8ToGbk((char*)value.c_str(), chrArrDesc);
						value = chrArrDesc;
						delete[] chrArrDesc;
					}
				}
				mDataValues.insert(std::pair<string, string>(vDataIDs[r - 9] + name, value));
			}
		}
		nCurrentCol += dim.lastCol;
	}

	int nDataCount = 0;
	if (strFile.find("NPC") > 0 && strFile.find("NPC") < strFile.size())
	{
		int a = 0;
	}
	for (auto strID : vDataIDs)
	{
		auto objectNode = iniDoc->NewElement("Object");
		root->LinkEndChild(objectNode);
		for (auto strColName : vColNames)
		{
			if (strColName == "Id")
			{
				const char* chrID = objectNode->Attribute("Id");
				if (!chrID)
				{
					objectNode->SetAttribute(strColName.c_str(), mDataValues[strID + strColName].c_str());
				}
			}
			else
			{
				objectNode->SetAttribute(strColName.c_str(), mDataValues[strID + strColName].c_str());
			}
			nDataCount++;
		}
	}

	////////////////////////////////////////////////////////////////////////////
	// 保存文件
	int nLastPoint = strFile.find_last_of(".") + 1;
	int nLastSlash = strFile.find_last_of("/") + 1;
	std::string strFileName = strFile.substr(nLastSlash, nLastPoint - nLastSlash - 1);
	std::string strFileExt = strFile.substr(nLastPoint, strFile.length() - nLastPoint);

	std::string strXMLFile = strToolBasePath + strXMLIniPath + strFileName;
	if (nCipher > 0)
	{
		strXMLFile += ".NF";
	}
	else
	{
		strXMLFile += ".xml";
	}

	iniDoc->SetBOM(false);
	iniDoc->SaveFile(strXMLFile.c_str());
	delete iniDoc;
	delete x;
	return true;
}
Example #2
0
bool DatasetCommand::ParseXlsx(const char *pPath)
{
	MiniExcelReader::ExcelFile excelFile;

	if(!excelFile.open(pPath))
		return false;

	auto &sheets = excelFile.sheets();
	
	std::string strXlsxName = GetFileName(pPath, false);

	for(auto i = 0; i < sheets.size(); i++)
	{
		auto &sheet = sheets[i];
		// 索引不是从 0  开始的 需要注意一下
		auto &range = sheet.getDimension();

		std::string sheetName = strXlsxName;
		if(sheets.size() > 1 && sheetName != sheet.getName())
		{
			sheetName.append("_");
			sheetName.append(sheet.getName());
		}
		std::cout << sheetName << std::endl;
		
		// 获取导出标记
		std::vector<bool> vecExportFlag;
		vecExportFlag.resize(sheet.getDimension().lastCol-1);
		bool bHasExport = false;
		int nMaxCol;
		for(int col = 2; col <= range.lastCol; col++)
		{
			auto cell = sheet.getCell(4, col);
			if(cell == NULL)
				break;
			int nTag = atoi(cell->value.c_str());
			vecExportFlag[col-2] = nTag == 0 || nTag == m_nTag;
			if(!bHasExport)
				bHasExport = vecExportFlag[col-2];

			nMaxCol = col;
		}

		if(!bHasExport)
		{
			continue ;
		}
		auto &vecProperty = m_mapTable[sheetName];
		auto &vecEnum = m_mapTableEnum[sheetName];

		std::string strHeader;
		std::string strType;

		for(int col = 2; col <= nMaxCol; col++)
		{
			if(vecExportFlag[col-2])
			{
				auto cell1 = sheet.getCell(NAME_ROW, col);
				strHeader.append(cell1->value);
				strHeader.append(",");

				auto cell2 = sheet.getCell(TYPE_ROW, col);
				strType.append(cell2->value);
				strType.append(",");

				auto cell3 = sheet.getCell(DESC_ROW, col);
				DBData data;
				data.strName = cell1->value;
				data.strType = cell2->value;
				data.strDesc = cell3->value;
				vecProperty.push_back(data);
			}
		}

		// 导出csv
		if(bHasExport && m_strCSVDir.size() > 0)
		{
			strHeader.pop_back();
			strType.pop_back();
			strHeader.append("\n");
			strType.append("\n");

			std::string strContent;
			for(int row = CONTENT_ROW; row <= range.lastRow; row++)
			{
				auto cellEnum = sheet.getCell(row, 1);
				if(cellEnum && cellEnum->value.size() > 0)
				{
					DBData enumData;
					enumData.strName = cellEnum->value;
					cellEnum = sheet.getCell(row, 2);
					if(cellEnum && cellEnum->value.size() > 0)
					{
						enumData.strType = cellEnum->value;
					}
					cellEnum = sheet.getCell(row, 3);
					if(cellEnum && cellEnum->value.size() > 0)
					{
						enumData.strDesc = cellEnum->value;
					}
					vecEnum.push_back(enumData);
				}

				bool bHasData = false;
				
				for(int col = 2; col <= nMaxCol; col++)
				{
					auto cell = sheet.getCell(row, col);
					if(vecExportFlag[col-2])
					{
						bHasData = cell->value.size() > 0;
						if(bHasData)
							break;
					}
				}

				if(bHasData)
				{
					for(int col = 2; col <= nMaxCol; col++)
					{
						auto cell = sheet.getCell(row, col);
						if(vecExportFlag[col-2])
						{
							std::string strValue = cell->value;
							Utility_ReplaceString(strValue, "\"", "\"\"");
							if(strValue.find_first_of(',') != -1)
							{
								strValue.insert(0, "\"");
								strValue.push_back('\"');
							}
							strContent.append(strValue);
							strContent.append(",");
						}
					}
					strContent.pop_back();
					strContent.append("\n");
				}
			}

			CreatDir((char*)m_strCSVDir.c_str());

			FILE *fp = fopen((m_strCSVDir+sheetName+".csv").c_str(), "wb");

			fwrite(strHeader.c_str(), strHeader.size(), 1, fp);
			fwrite(strType.c_str(), strType.size(), 1, fp);
			fwrite(strContent.c_str(), strContent.size(), 1, fp);

			fclose(fp);
		}
	}

	return true;
}
Example #3
0
bool FileProcess::CreateStructXML(std::string strFile, std::string strFileName)
{
	std::cout << strFile << std::endl;
	// 打开excel
	MiniExcelReader::ExcelFile* x = new MiniExcelReader::ExcelFile();
	if (!x->open(strFile.c_str()))
	{
		printf("can't open %s\n", strFile.c_str());
		return false;
	}

	// PropertyName
	// cpp
	std::string strHPPPropertyInfo = "";
	std::string strHppRecordInfo = "";
	std::string strHppEnumInfo = "";

	strHPPPropertyInfo = strHPPPropertyInfo + "class " + strFileName + "\n{\npublic:\n";
	strHPPPropertyInfo = strHPPPropertyInfo + "\t//Class name\n\tstatic const std::string& ThisName(){ static std::string x" + strFileName + " = \"" + strFileName + "\";" + " return x" + strFileName + "; }\n" + "\t// IObject\n" + strHppIObjectInfo + "\t// Property\n";

	// java
	std::string strJavaPropertyInfo = "";
	std::string strJavaRecordInfo = "";
	std::string strJavaEnumInfo = "";

	strJavaPropertyInfo = strJavaPropertyInfo + "public class " + strFileName + " {\n";
	strJavaPropertyInfo = strJavaPropertyInfo + "\t//Class name\n\tpublic static final String ThisName = \"" + strFileName + "\";\n\t// IObject\n" + strJavaIObjectInfo + "\t// Property\n";

	// C#
	std::string strCSPropertyInfo = "";
	std::string strCSRecordInfo = "";
	std::string strCSEnumInfo = "";

	strCSPropertyInfo = strCSPropertyInfo + "public class " + strFileName + "\n{\n";
	strCSPropertyInfo = strCSPropertyInfo + "\t//Class name\n\tpublic static readonly string ThisName = \"" + strFileName + "\";\n\t// IObject\n" + strCSIObjectInfo + "\t// Property\n";

	// 开始创建xml
	tinyxml2::XMLDocument* structDoc = new tinyxml2::XMLDocument();
	if (NULL == structDoc)
	{
		return false;
	}
	//xml声明
	tinyxml2::XMLDeclaration *pDel = structDoc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
	if (NULL == pDel)
	{
		return false;
	}

	structDoc->LinkEndChild(pDel);

	// 写入XML root标签
	tinyxml2::XMLElement* root = structDoc->NewElement("XML");
	structDoc->LinkEndChild(root);

	// 写入Propertys标签
	tinyxml2::XMLElement* propertyNodes = structDoc->NewElement("Propertys");
	root->LinkEndChild(propertyNodes);

	// 写入Records标签
	tinyxml2::XMLElement* recordNodes = structDoc->NewElement("Records");
	root->LinkEndChild(recordNodes);

	// 写入components的处理
	tinyxml2::XMLElement* componentNodes = structDoc->NewElement("Components");
	root->LinkEndChild(componentNodes);

	// 读取excel中每一个sheet
	std::vector<MiniExcelReader::Sheet>& sheets = x->sheets();
	for (MiniExcelReader::Sheet& sh : sheets)
	{
		std::string strSheetName = sh.getName();

		const MiniExcelReader::Range& dim = sh.getDimension();

		std::string strUpperSheetName = strSheetName.substr(0, 8);
		transform(strUpperSheetName.begin(), strUpperSheetName.end(), strUpperSheetName.begin(), ::tolower);
		if (strUpperSheetName == "property")
		{
			std::vector<std::string> colNames;
			for (int r = dim.firstRow; r <= dim.firstRow + 7; r++)
			{
				MiniExcelReader::Cell* cell = sh.getCell(r, dim.firstCol);
				if (cell)
				{
					colNames.push_back(cell->value);
				}
			}

			for (int c = dim.firstCol + 1; c <= dim.lastCol; c++)
			{
				std::string testValue = "";
				MiniExcelReader::Cell* cell = sh.getCell(dim.firstRow, c);
				if (cell)
				{
					testValue = cell->value;
				}
				if (testValue == "")
				{
					continue;
				}

				auto propertyNode = structDoc->NewElement("Property");
				propertyNodes->LinkEndChild(propertyNode);
				std::string strType = "";
				for (int r = dim.firstRow; r <= dim.firstRow + 7; r++)
				{
					std::string name = colNames[r - 1];
					std::string value = "";
					MiniExcelReader::Cell* cell = sh.getCell(r, c);
					if (cell)
					{
						std::string valueCell = cell->value;
						transform(valueCell.begin(), valueCell.end(), valueCell.begin(), ::toupper);
						if (valueCell == "TRUE" || valueCell == "FALSE")
						{
							value = valueCell == "TRUE" ? 1 : 0;
						}
						else
						{
							value = cell->value;
						}

						if (name == "Type")
						{
							strType = value;
						}

					}
					propertyNode->SetAttribute(name.c_str(), value.c_str());
				}

				strHPPPropertyInfo = strHPPPropertyInfo + "\tstatic const std::string& " + testValue + "(){ static std::string x" + testValue + " = \"" + testValue + "\";" + " return x" + testValue + "; } // " + strType + "\n";
				strJavaPropertyInfo = strJavaPropertyInfo + "\tpublic static final String " + testValue + " = \"" + testValue + "\"; // " + strType + "\n";
				strCSPropertyInfo = strCSPropertyInfo + "\tpublic static readonly String " + testValue + " = \"" + testValue + "\"; // " + strType + "\n";

				if (strFileName == "IObject")
				{
					strHppIObjectInfo += "\tstatic const std::string& " + testValue + "(){ static std::string x" + testValue + " = \"" + testValue + "\";" + " return x" + testValue + "; } // " + strType + "\n";
					strJavaIObjectInfo += "\tpublic static final String " + testValue + " = \"" + testValue + "\"; // " + strType + "\n";
					strCSIObjectInfo += "\tpublic static readonly String " + testValue + " = \"" + testValue + "\"; // " + strType + "\n";
				}
			}
		}
		else if (strUpperSheetName == "componen")
		{
			std::vector<std::string> colNames;
			for (int c = dim.firstCol; c <= dim.lastCol; c++)
			{
				MiniExcelReader::Cell* cell = sh.getCell(dim.firstRow, c);
				if (cell)
				{
					colNames.push_back(cell->value);
				}
			}
			for (int r = dim.firstRow + 1; r <= dim.lastRow; r++)
			{
				std::string testValue = "";
				MiniExcelReader::Cell* cell = sh.getCell(r, dim.firstCol);
				if (cell)
				{
					testValue = cell->value;
				}
				if (testValue == "")
				{
					continue;
				}
				auto componentNode = structDoc->NewElement("Component");
				componentNodes->LinkEndChild(componentNode);
				std::string strType = "";
				for (int c = dim.firstCol; c <= dim.lastCol; c++)
				{
					std::string name = colNames[c - 1];
					std::string value = "";
					MiniExcelReader::Cell* cell = sh.getCell(r, c);
					if (cell)
					{
						std::string valueCell = cell->value;
						transform(valueCell.begin(), valueCell.end(), valueCell.begin(), ::toupper);
						if (valueCell == "TRUE" || valueCell == "FALSE")
						{
							value = valueCell == "TRUE" ? 1 : 0;
						}
						else
						{
							value = cell->value;
						}

						if (name == "Type")
						{
							strType = value;
						}

					}
					componentNode->SetAttribute(name.c_str(), value.c_str());
				}
			}
		}
		else
		{
			const int nRowsCount = dim.lastRow - dim.firstRow + 1;
			const int nRecordCount = nRowsCount / 10;

			if (nRowsCount != nRecordCount * 10)
			{
				printf("This Excel[%s]'s Record is something wrong, Sheet[%s] Total Rows is %d lines, Not 10*N\n", strFile.c_str(), strSheetName.c_str(), nRowsCount);
				printf("Generate faild!\n");
				printf("Press [Enter] key to exit!\n");
				std::cin.ignore();
				exit(1);
			}

			for (int nCurrentRecord = 1; nCurrentRecord <= nRecordCount; nCurrentRecord++)
			{
				std::string strRecordName = "";
				std::string strRow = "";
				std::string strCol = "";
				std::string strPublic = "";
				std::string strPrivate = "";
				std::string strSave = "";
				std::string strCache = "";
				std::string strDesc = "";

				MiniExcelReader::Cell* cell = sh.getCell((nCurrentRecord - 1) * 10 + 1, 2);
				if (cell)
				{
					strRecordName = cell->value;
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 2, 2);
				if (cell)
				{
					strRow = cell->value;
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 3, 2);
				if (cell)
				{
					strCol = cell->value;
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 4, 2);
				if (cell)
				{
					if (cell->value == "TRUE" || cell->value == "FALSE")
					{
						strPublic = cell->value == "TRUE" ? 1 : 0;
					}
					else
					{
						strPublic = cell->value;
					}
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 5, 2);
				if (cell)
				{
					if (cell->value == "TRUE" || cell->value == "FALSE")
					{
						strPrivate = cell->value == "TRUE" ? 1 : 0;
					}
					else
					{
						strPrivate = cell->value;
					}
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 6, 2);
				if (cell)
				{
					if (cell->value == "TRUE" || cell->value == "FALSE")
					{
						strSave = cell->value == "TRUE" ? 1 : 0;
					}
					else
					{
						strSave = cell->value;
					}
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 7, 2);
				if (cell)
				{
					if (cell->value == "TRUE" || cell->value == "FALSE")
					{
						strCache = cell->value == "TRUE" ? 1 : 0;
					}
					else
					{
						strCache = cell->value;
					}
				}
				cell = nullptr;
				cell = sh.getCell((nCurrentRecord - 1) * 10 + 10, 2);
				if (cell)
				{
					strDesc = cell->value;
				}
				cell = nullptr;

				const int nExcelCols = atoi(strCol.c_str());
				int nRealCols = 0;

				auto recordNode = structDoc->NewElement("Record");
				recordNodes->LinkEndChild(recordNode);

				recordNode->SetAttribute("Id", strRecordName.c_str());
				recordNode->SetAttribute("Row", strRow.c_str());
				recordNode->SetAttribute("Col", strCol.c_str());
				recordNode->SetAttribute("Public", strPublic.c_str());
				recordNode->SetAttribute("Private", strPublic.c_str());
				recordNode->SetAttribute("Save", strSave.c_str());
				recordNode->SetAttribute("Cache", strCache.c_str());
				recordNode->SetAttribute("Desc", strDesc.c_str());

				strHppRecordInfo = strHppRecordInfo + "\tstatic const std::string& R_" + strRecordName + "(){ static std::string x" + strRecordName + " = \"" + strRecordName + "\";" + " return x" + strRecordName + ";}\n";
				strHppEnumInfo = strHppEnumInfo + "\n\tenum " + strRecordName + "\n\t{\n";

				strJavaRecordInfo = strJavaRecordInfo + "\tpublic static final String R_" + strRecordName + " = \"" + strRecordName + "\";\n";
				strJavaEnumInfo = strJavaEnumInfo + "\n\tpublic enum " + strRecordName + "\n\t{\n";

				strCSRecordInfo = strCSRecordInfo + "\tpublic static readonly String R_" + strRecordName + " = \"" + strRecordName + "\";\n";
				strCSEnumInfo = strCSEnumInfo + "\n\tpublic enum " + strRecordName + "\n\t{\n";

				std::string toWrite = "enum " + strRecordName + "\n{\n";
				fwrite(toWrite.c_str(), toWrite.length(), 1, protoWriter);


				for (int nRecordCol = dim.firstCol;nRecordCol <= dim.lastCol;nRecordCol++)
				{
					std::string strType = "";
					std::string strTag = "";
					cell = sh.getCell((nCurrentRecord - 1) * 10 + 8, nRecordCol);
					if (cell)
					{
						strTag = cell->value;
					}
					else
					{
						break;
					}
					cell = nullptr;
					cell = sh.getCell((nCurrentRecord - 1) * 10 + 9, nRecordCol);
					if (cell)
					{
						strType = cell->value;
					}
					else
					{
						break;
					}

					cell = nullptr;

					auto colNode = structDoc->NewElement("Col");
					recordNode->LinkEndChild(colNode);

					colNode->SetAttribute("Type", strType.c_str());
					colNode->SetAttribute("Tag", strTag.c_str());

					toWrite = "\t" + strTag + "\t\t= " + std::to_string(nRecordCol - 1) + "; // " + strTag + " -- " + strType + "\n";
					fwrite(toWrite.c_str(), toWrite.length(), 1, protoWriter);

					strHppEnumInfo += "\t\t" + strRecordName + "_" + strTag + "\t\t= " + std::to_string(nRecordCol - 1) + ", // " + strTag + " -- " + strType + "\n";
					strJavaEnumInfo += "\t\t" + strTag + "\t\t= " + std::to_string(nRecordCol - 1) + ", // " + strTag + " -- " + strType + "\n";
					strCSEnumInfo += "\t\t" + strTag + "\t\t= " + std::to_string(nRecordCol - 1) + ", // " + strTag + " -- " + strType + "\n";

					nRealCols++;
				}

				if (nExcelCols != nRealCols)
				{
					printf("This Excel[%s]'s format is something wrong, Record[%s] field \"col\"==%d not equal the real cols==%d!\n", strFile.c_str(), strRecordName.c_str(), nExcelCols, nRealCols);
					printf("Press [Enter] key to exit!");
					std::cin.ignore();
					exit(1);
				}

				fwrite("}\n", 2, 1, protoWriter);

				strHppEnumInfo += "\n\t};\n";
				strJavaEnumInfo += "\n\t};\n";
				strCSEnumInfo += "\n\t};\n";
			}
		}
	}
	// cpp
	strHPPPropertyInfo += "\t// Record\n" + strHppRecordInfo + strHppEnumInfo + "\n};\n\n";
	fwrite(strHPPPropertyInfo.c_str(), strHPPPropertyInfo.length(), 1, hppWriter);

	// java
	strJavaPropertyInfo += "\t// Record\n" + strJavaRecordInfo + strJavaEnumInfo + "\n}\n\n";
	fwrite(strJavaPropertyInfo.c_str(), strJavaPropertyInfo.length(), 1, javaWriter);

	// C#
	strCSPropertyInfo += "\t// Record\n" + strCSRecordInfo + strCSEnumInfo + "\n}\n\n";
	fwrite(strCSPropertyInfo.c_str(), strCSPropertyInfo.length(), 1, csWriter);

	////////////////////////////////////////////////////////////////////////////
	// 保存文件
	std::string strFilePath(strFile);
	int nLastPoint = strFilePath.find_last_of(".") + 1;
	int nLastSlash = strFilePath.find_last_of("/") + 1;
	std::string strFileExt = strFilePath.substr(nLastPoint, strFilePath.length() - nLastPoint);

	std::string strXMLFile = strToolBasePath + strXMLStructPath + strFileName;
	if (nCipher > 0)
	{
		strXMLFile += ".NF";
	}
	else
	{
		strXMLFile += ".xml";
	}
	structDoc->SetBOM(false);
	structDoc->SaveFile(strXMLFile.c_str());
	delete structDoc;
	delete x;
	return true;
}