在上一篇文章《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>
好了,基本上到终结了
【热爱工作,热爱生活】