现在的位置: 首页 > 综合 > 正文

TinyXML来操作XML文件(C++)<二>

2018年02月09日 ⁄ 综合 ⁄ 共 7632字 ⁄ 字号 评论关闭

在上一篇文章《TinyXML来操作XML文件(C++)》我们练习了创建XML、读取XML的方法,在本文中我们继续学习XML文件的增删改操作:包括读取声明、读取某结点文本属性、删去某结点、修改结点属性文本,增加结点操作

读取XML声明:

void ReadDeclaration(char *FileName,string& version,string& standalone,string& encoding)
{
	TiXmlDocument *pDoc = new TiXmlDocument();
	pDoc->LoadFile(FileName);
	TiXmlNode *pNode = pDoc->FirstChild();
	if(pNode != NULL)
	{
		TiXmlDeclaration *pDecalration = pNode->ToDeclaration();//获取声明指针
		if(pDecalration != NULL)
		{
		
			version = pDecalration->Version();
			standalone = pDecalration->Standalone();
			encoding = pDecalration->Encoding();

		}
	}
}

 

下来是读取某结点文本,既然是某结点,那么我们首先要找到该节点,获取到该节点指针,通过此指针对其进行修改

查找结点:

bool FindNode(TiXmlElement *pRoot,const string &NodeName,TiXmlElement *&pNode)
{
	if (pRoot->Value() == NodeName)
	{
		pNode = pRoot;
		return true;
	}
	TiXmlElement *p = pRoot;
	for (pRoot = p->FirstChildElement();pRoot; pRoot = pRoot->NextSiblingElement())
	{
		FindNode(pRoot,NodeName,pNode);
		return true;
	}
	return false;
}

 上述代码效果

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	string version,standalone,encoding;
	ReadDeclaration(Filename,version,standalone,encoding);
	cout <<"version: "<<version<<" standalone: "<<standalone<<"  encoding:"<<encoding<<endl;
                return 0;
}

运行结果:
<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
version: 1.0 standalone:   encoding:
读取某结点文本:(注意这里的文本意思是<node></node>间的文本,所以不要用此方法来读取属性,好挫,我就是在这个问题上卡住好半天

bool GetText(char *FileName,const string&NodeName,char* Text)
{
	//读节点文本值
    TiXmlDocument *pDoc = new TiXmlDocument();
	pDoc->LoadFile(FileName);
	if (pDoc == NULL)
	{
		return false;
	}
	TiXmlElement *pRoot = pDoc->RootElement();
	if (pRoot == NULL)
	{
		return false;
	}
	TiXmlElement *pNode = NULL;
	FindNode(pRoot,NodeName,pNode);//查找结点
	char *p = new char[100];
	if (pNode != NULL)
	{
		
		strcpy(Text,pNode->GetText());
		return true;
	}

	else
		return false;
}

上述代码效果:

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Before Change---------------------"<<endl;
	char* Text = new char[100];
	memset(Text,'\0',sizeof(Text));
	GetText(Filename,"Child",Text);
	cout <<"Text:"<<Text<<endl;
                return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results----------------
WYY

读取某结点属性

bool ReadAttribution(const char * FileName,const string& NodeName,map<string,string>& refmap)//用一个map来存储XML结点属性及属性值
{
		TiXmlDocument *pDoc = new TiXmlDocument();
		pDoc->LoadFile(FileName);
		if (pDoc == NULL)
		{
			return false;
		}
		TiXmlElement *pRoot = pDoc->RootElement();
		if (pRoot == NULL)
		{
			return false;
		}
		TiXmlElement *pNode = NULL;
		FindNode(pRoot,NodeName,pNode);
		if (pNode == NULL)
		{
				return false;
		}
	   TiXmlAttribute *pAttr = NULL;
	   for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())
	   {
				string name = pAttr->Name();
				string value = pAttr->Value();
				refmap.insert(make_pair(name,value));
	   }
		return true;
}

上述代码效果:

nt main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Results---------------------"<<endl;
	map<string,string> mapAttr;
	ReadAttribution(Filename,"Child2",mapAttr);
	map<string,string>::iterator itr = mapAttr.begin();
	for (;itr!= mapAttr.end(); itr++)
	{
		cout << itr->first<<"    "<<itr->second<<endl;
	}
return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results------------------
name    History
owner    xue
删去某结点;

bool DelNode(const char *FileName,const string& NodeName)
{
	TiXmlDocument  *pDoc = new TiXmlDocument();
	pDoc->LoadFile(FileName);
	if (pDoc == NULL)
	{
		return false;
	}
	TiXmlElement *pRoot = pDoc->RootElement();
	if (pRoot == NULL)
		return false;
		
	TiXmlElement *pNode =NULL;
	FindNode(pRoot,NodeName,pNode);
	if (pNode == NULL)
	{
		return false;
	}
	if (pNode == pRoot)
	{//如果是根节点
		pDoc->RemoveChild(pRoot);
		pDoc->SaveFile(FileName);
		return true;
	}
	else
	{
	
	     TiXmlNode  *p = pNode->Parent();//首先获取该节点的父节点,完了再删去该父节点的子节点即我们想要删去的结点
		 if (p == NULL)
		 {
			 return false;
		 }
		 TiXmlElement *pElement = p->ToElement();
		 if (pElement == NULL)
		 {
			 return false;
		 }
		 pElement->RemoveChild(pNode);
		 pDoc->SaveFile(FileName);//最后不要忘记保存
		 return true;
	}
	delete pDoc;
	pDoc = NULL;
     return false;
}

上述代码效果:

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Results---------------------"<<endl;
	DelNode(Filename,"Child2");
	ReadXML(Filename);
                return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results------------------
<?xml version="1.0" ?>
<Root>Book
    <Child>WYY</Child>
</Root>

 

修改结点文本操作: 

bool modifyTextandInsert(char *FileName,const string&NodeName,const char* Text)
{
      TiXmlDocument *pDoc = new TiXmlDocument();
	  pDoc->LoadFile(FileName);
	
	  TiXmlElement *pRoot = pDoc->RootElement();
	  if (pRoot == NULL)
	  {
		  return false;
	  }
	  TiXmlElement *pNode = NULL;
	  FindNode(pRoot,NodeName,pNode);
	  if (pNode == NULL)
		  return false;
	 
	  pNode->Clear();//先删去原文本
	  TiXmlText *pText = new TiXmlText(Text);//重新new一个Text
	  pNode->LinkEndChild(pText);//将节点与新Text关联
	  pDoc->SaveFile(FileName);

	  delete pDoc;
	  pDoc = NULL;
	  return true;


}

上述代码效果:

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Results---------------------"<<endl;
	modifyText(Filename,"Child","LOVE");
	ReadXML(Filename);
 return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results------------------
<?xml version="1.0" ?>
<Root>Book
    <Child>LOVE</Child>
</Root>

修改属性:

bool modifyAttribution(const char * FileName,const string & NodeName,map<string,const char *>& refmap)
{
	TiXmlDocument *pDoc = new TiXmlDocument();
	pDoc->LoadFile(FileName);
	if (pDoc == NULL)
	{
		return false;
	}
	TiXmlElement *pRoot = pDoc->RootElement();
	if (pRoot == NULL)
	{
		return false;
	}
	TiXmlElement *pNode = NULL;
	FindNode(pRoot,NodeName,pNode);
	if(pNode == NULL)
		return false;
	TiXmlAttribute *pAttr = pNode->FirstAttribute();
	map<string,const char*>::iterator itr = refmap.begin();
	char *  strName = NULL ;
	for (; pAttr; pAttr = pAttr->Next())
	{
			strName = const_cast<char *>(pAttr->Name());
			for (itr; itr!= refmap.end(); ++itr)
			{
				if (strName == itr->first) 
				{
					pNode->SetAttribute(strName,itr->second);
				}
			}
	}
	pDoc->SaveFile(FileName);


	delete pDoc;
	pDoc = NULL;
	return true;
}

上述代码效果:

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Results---------------------"<<endl;
	map<string,const char*>mapAttr;
	mapAttr.insert(make_pair("name","Math"));
	modifyAttribution(Filename,"Child2",mapAttr);
	ReadXML(Filename);
	return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results-------------------
<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="Math" owner="xue" />
    </Child>
</Root>

新增结点:

bool InsertText(char *FileName,const string&NodeName,const char * newName,const char* Text)
{
      TiXmlDocument *pDoc = new TiXmlDocument();
	  pDoc->LoadFile(FileName);
	
	  TiXmlElement *pRoot = pDoc->RootElement();
	  if (pRoot == NULL)
	  {
		  return false;
	  }
	  TiXmlElement *pNode = NULL;
	  FindNode(pRoot,NodeName,pNode);
	  if (pNode == NULL)
		  return false;
	//新增结点
	 TiXmlElement *pNew = new TiXmlElement(newName);
	  TiXmlText *pInsert = new TiXmlText(Text);
	  pNew->LinkEndChild(pInsert);
	  pNode->InsertEndChild(*pNew);

	  pDoc->SaveFile(FileName);

	  delete pDoc;
	  pDoc = NULL;
	  return true;
}

上述代码效果:

int main(int argc, char **argv)
{
	
	char* Filename = "myXml.xml";
	CreateXML(Filename);
	ReadXML(Filename);
	cout <<"----------------------Results---------------------"<<endl;
    InsertText(Filename,"Child","Child3","new Child");
	ReadXML(Filename);
	return 0;
}

运行结果:

<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
    </Child>
</Root>
----------------------Results--------------------
<?xml version="1.0" ?>
<Root>Book
    <Child>WYY
        <Child2 name="History" owner="xue" />
        <Child3>new Child</Child3>
    </Child>
</Root>

好了,基本上到终结了

 

 

                                                                                            【热爱工作,热爱生活】

抱歉!评论已关闭.