读取和设置xml配置文件是最常用的操作,TinyXML是一个开源的解析XML的C++解析库,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
Tinyxml的官方网址:http://www.grinninglizard.com
官方介绍文档:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html
使用TinyXML只需要将其中的6个文件拷贝到项目中就可以直接使用了,这六个文件是:tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp
在TinyXML中,根据XML的各种元素来定义了一些类:
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释
TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
<?xml version="1.0" ?> //TiXmlDeclaration,声明
<MyApp> //TiXmlElement,元素
<!-- Settings for MyApp -->//TiXmlComment,注释
<Messages>//TiXmlElement,元素
<Welcome>Welcome to MyApp</Welcome>
//<Welcome>是元素TiXmlElement ,“Welcome to MyApp”是TiXmlText,文本
<Farewell>Thank you for using MyApp</Farewell>//同上
</Messages>
<Windows>//TiXmlElement,元素
<Window name="MainFrame" x="5" y="15" w="400" h="250" />
// Window是元素TiXmlElement ,name、x、y、h是TiXmlAttribute
</Windows>
<Connection ip="192.168.0.1" timeout="123.456000" />
</MyApp>
TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。
注意,TiXmlBase 是TiXmlNode的基类,TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类。
例程:
#pragma onece
#include "tinystr.h"
#include "tinyxml.h"
#include <string>
#include <stack>
using namespace std;
enum SuccessEnum {FAILURE, SUCCESS};
TiXmlElement ReadXmlByStack(char* InputInfo, char* pName,int iXMLType, bool& bFind)
{
TiXmlDocument cXmlDoc;
TiXmlElement* pRootElement = NULL;
stack<TiXmlElement*> ElementStack;
bFind = false;
if (iXMLType == 1)
{
if (!cXmlDoc.LoadFile(InputInfo))
{
printf("parse XML file failed \n");
return TiXmlElement("");
}
}
else if (iXMLType == 2)
{
if (!cXmlDoc.Parse(InputInfo))
{
printf("parse XML failed \n");
return TiXmlElement("");
}
}
pRootElement = cXmlDoc.RootElement();
if (NULL == pRootElement)
{
printf("no have root Element\n");
return TiXmlElement("");
}
else
{
ElementStack.push(pRootElement);
TiXmlElement* pTempElement = NULL;
while(ElementStack.size() > 0)
{
pTempElement = ElementStack.top();
//printf("%s\n", pTempElement->Value());
ElementStack.pop();
if (0 == strcmp(pTempElement->Value(), pName) )
{
bFind = true;
break;
}
TiXmlElement* pTempSibLing = pTempElement->FirstChildElement();
do
{
if (pTempSibLing)
{
ElementStack.push(pTempSibLing);
pTempSibLing = pTempSibLing->NextSiblingElement();
}
}while(pTempSibLing);
}
while(ElementStack.size() > 0)
{
ElementStack.pop();
}
if (bFind)
{
return *pTempElement;
}
else
{
return TiXmlElement("");
}
}
}
void creat_xml()
{
#if 0
const char demoStart[] =
"<?xml version=\"1.0\" standalone='no' >\n"
"<!-- Our to do list data -->"
"<ToDo>\n"
"<!-- Do I need a secure PDA? -->\n"
"<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
"<Item priority=\"2\" distance='none'> Do bills </Item>"
"<Item priority=\"2\" distance='far & back'> Look for Evil Dinosaurs! </Item>"
"</ToDo>";
TiXmlDocument doc("demotest.xml");
doc.Parse(demoStart);
if ( doc.Error() )
{
printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
exit( 1 );
}
doc.SaveFile();
#endif
TiXmlDocument* doc = new TiXmlDocument();
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
doc->LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("AgentInfo");
doc->LinkEndChild(root);
TiXmlElement* said = new TiXmlElement("said");
said->SetAttribute("value", "chinese");
root->LinkEndChild(said);
#if 1
TiXmlElement* country = new TiXmlElement("country");
country->SetAttribute("name", "country");
said->LinkEndChild(country);
#endif
/*LinkEndChild TiXmlText*/
TiXmlElement* msg = new TiXmlElement( "Welcome" );
msg->LinkEndChild(new TiXmlText( "Welcome to MyApp" ));
said->LinkEndChild(msg);
TiXmlElement* msg_n = new TiXmlElement( "Welcome" );
msg_n->LinkEndChild(new TiXmlText( "Welcome to MyApp_m" ));
said->LinkEndChild(msg_n);
TiXmlElement* basePath = new TiXmlElement("basePath");
basePath->SetAttribute("value","mypath" );
root->LinkEndChild(basePath);
TiXmlElement* cert = new TiXmlElement("cert");
cert->SetAttribute("value","cert_n");
cert->SetAttribute("value_01","cert_01");
cert->SetAttribute("value_02","cert_02");
root->LinkEndChild(cert);
/*InsertAfterChild InsertBeforeChild*/
TiXmlElement* cert_a = new TiXmlElement("cert_a");
cert_a->SetAttribute("value","cert_after");
root->InsertAfterChild(cert,*cert_a);
TiXmlElement* collway = new TiXmlElement("collway");
collway->SetAttribute("value", "1001");
root->LinkEndChild(collway);
TiXmlElement* version = new TiXmlElement("version");
version->SetAttribute("value", "10.12.189");
root->LinkEndChild(version);
doc->SaveFile("demotest.xml");
delete doc;
return;
}
int find_xml()
{
bool re;
TiXmlElement lpItem = ReadXmlByStack("demotest.xml","cert",1,re);
if(!re)
{printf("get element erro"); return -1;}
/*fine the cert's value*/
printf("element is %s\t",lpItem.Value());
printf("value is %s\n",lpItem.Attribute("value_01"));
TiXmlAttribute* pAttr = NULL;
/*Traversing all Attribute*/
for(pAttr = lpItem.FirstAttribute();pAttr != NULL;pAttr = pAttr->Next())
printf("the value is %s\n",pAttr->Value());
return 0;
}
int chage_xml()
{
TiXmlDocument* doc = new TiXmlDocument();
if(!doc->LoadFile("demotest.xml"))
{
printf("loadfile erro\n");
return -1;
}
//change element value
#if 1
TiXmlElement * rootelement = doc->RootElement();
TiXmlElement * firstchild = rootelement->FirstChildElement();
firstchild->SetAttribute("value","changed");
#endif
doc->SaveFile("demotest.xml");
doc->Clear();
delete doc;
return 0;
}
void add_xml()
{
return;
}
int delete_xml()
{
bool re;
TiXmlDocument * deletXML = new TiXmlDocument();
if(!deletXML->LoadFile("demotest.xml"))
{
printf("loadfile erro\n");
return -1;
}
//delete element
#if 0
TiXmlElement * rootelement = deletXML->RootElement();
TiXmlNode* removeThis = rootelement->FirstChild();
if(!strcmp(removeThis->Value(),"cert_a"))
{rootelement->RemoveChild(removeThis);}
else
{
for(TiXmlNode* nextnode = removeThis->NextSibling();
nextnode !=NULL;nextnode = nextnode->NextSibling())
{
if(!strcmp(nextnode->Value(),"cert_a"))
{rootelement->RemoveChild(nextnode); break;}
}
}
#endif
//delete atrubiute
TiXmlElement * rootelement = deletXML->RootElement();
TiXmlElement * removeThis = rootelement->FirstChildElement();
if(!strcmp(rootelement->Value(),"cert"))
{rootelement->RemoveAttribute("value_01");}
else
{
for(TiXmlElement* nextelement = removeThis->NextSiblingElement();
nextelement !=NULL;nextelement = nextelement->NextSiblingElement())
{
if(!strcmp(nextelement->Value(),"cert"))
{nextelement->RemoveAttribute("value_01"); break;}
}
}
deletXML->SaveFile("demotest.xml");
deletXML->Clear();
delete deletXML;
return 0;
}
int print_xml()
{
TiXmlDocument *lconfigXML = new TiXmlDocument();
if(!lconfigXML->LoadFile("demotest.xml"))
{
printf("loadfile erro\n");
return -1;
}
TiXmlElement* rootElement = lconfigXML->RootElement();
if(NULL == rootElement)
return -1;
printf("%s:\t\n", rootElement->Value());
//can't do this
//printf("%s\n",rootElement->Attribute("value"));
TiXmlElement* element = rootElement->FirstChildElement();
if (element == NULL)
return -1;
printf("%s:\t%s\n", element->Value(), element->Attribute("value"));
for(element = element->NextSiblingElement();
element !=NULL;element = element->NextSiblingElement())
printf("%s:\t%s\n", element->Value(), element->Attribute("value"));
lconfigXML->Clear();
delete lconfigXML;
return 0;
}
int main()
{
creat_xml();
printf("-----------\n");
print_xml();
printf("-----------\n");
find_xml();
printf("-----------\n");
delete_xml();
printf("-----------\n");
print_xml();
printf("-----------\n");
delete_xml();
printf("-----------\n");
find_xml();
chage_xml();
printf("-----------\n");
print_xml();
return 0;
}
参考链接:https://www.cnblogs.com/cy568searchx/p/3670400.html