作者:如意蛋挞
资料来源: http://www.cnblogs.com/clever101
对于xml文件,我不太喜欢使用像msxml这样复杂的xml解析器,因为我现在的工作只是专注于将它用作配置文件和简单的信息文件。 特别是使用msxml分析xml与复杂的com类型转换相关联,让人感到很繁琐。 因此,我们希望使用开源TinyXml来分析简单的xml文件。
让我先介绍一下TinyXml。 TinyXML是目前非常流行的基于DOM模型的XML解析器,简单易用,结构紧凑,非常适合简单的数据、配置文件、对象序列化等数据量不太大的操作。 其主页为http://www.grinning lizard.com/tinyxml /,目前最新版本为2.5 .
TinyXml有很多网上教程,但我觉得没怎么写(看完之后感觉不记得了)。 因为没办法,所以必须自己整理适合自己的东西。 至于是否适合别人,取决于仁见智。 我认为xml文件的本质是一个小数据库。 从另一个角度来看,你对数据库做了什么,你对xml文件做了什么才能实现。 通常,对数据库的操作包括创建新数据库、查询数据库、修改数据库和删除数据库。 相应的xml文件是创建一个新的xml文件,检查xml文件中指定节点的值,修改xml文件中节点的值,然后删除xml文件中节点的值。
首先,让我们知道一些xml文件的格式。 常见的xml文件格式如下。
example1.xml:
? XML版本=' 1.0 '?
HelloWorld/Hello
example2.xml:
? XML版本=' 1.0 '?
帕特里
验证
Alas
绿色世界
Alas(again )
/verse
/poetry
example3.xml:
? XML版本=' 1.0 '?
形状
circle name=' int-based ' x=' 20 ' y=' 30 ' r=' 50 ' /
point name=' float-based ' x=' 3.5 ' y=' 52.1 ' /
/shapes
example4.xml:
? XML版本=' 1.0 '?
MyApp
消息传递
欢迎使用欢迎屏幕
farewellthankyouforusingmyapp/farewell
/消息
Windows
窗口名称=' mainframe ' x='5' y=' 15 ' w=' 400 ' h=' 250 ' /
/Windows
连接IP=' 192.168.0.1 ' time out=' 123.456000 ' /
/MyApp
上面的例子摘自《TinyXML Tutorial中文指南》。 上面有四个例子。 你看到xml文件的一些表现了吗? 我看到了本质,但只是两种表现形式。 属性值在尖括号内,例如window name=' mainframe ' x='5' y=' 15 ' w=' 400 ' h=' 250 ' /和轻咖啡豆在尖括号外,例如welcomewelcometttetted
由于example4.xml很复杂,所以这里以tinyxml的使用为例进行说明。
Tinyxml使用两个编译选项:使用标准c的char *类型,还是使用STL的STD:3360string。 其中,要使用预处理器TIXML_USE_STL进行控制,请考虑到添加STD33603360string的STL的广泛使用及其强大功能,将TIXML_USE_STL添加到其中
首先,使用VS 2005打开tinyxmlSTL.dsp工程文件并静默编译
态库,debug版本为:tinyxmld_STL.lib,然后开始测试tinyxml库。我的测试计划是这样的:首先使用tinyxml库创建example4.xml,然后将其读出来,然后查询指定节点的属性或轻松的咖啡豆,再修改example4.xml(修改其中的一些节点值和删除其中一个节点,增加一个节点),然后再读出来以判断是否修改成功。具体是在VS 2005上新建一个控制台工程:Test,注意使用多字节字符集进行编译,同时添加。首先是创建xml文件的代码:
/*!
* brief 创建xml文件。
*
* param XmlFile xml文件全路径。
* return 是否成功。true为成功,false表示失败。
*/
bool CreateXml(std::string XmlFile)
{
// 定义一个TiXmlDocument类指针
TiXmlDocument *pDoc = new TiXmlDocument;
if (NULL==pDoc)
{
return false;
}
TiXmlDeclaration *pDeclaration = new TiXmlDeclaration(_T("1.0"),_T(""),_T(""));
if (NULL==pDeclaration)
{
return false;
}
pDoc->LinkEndChild(pDeclaration);
// 生成一个根节点:MyApp
TiXmlElement *pRootEle = new TiXmlElement(_T("MyApp"));
if (NULL==pRootEle)
{
return false;
}
pDoc->LinkEndChild(pRootEle);
// 生成子节点:Messages
TiXmlElement *pMsg = new TiXmlElement(_T("Messages"));
if (NULL==pMsg)
{
return false;
}
pRootEle->LinkEndChild(pMsg);
// 生成子节点:Welcome
TiXmlElement *pWelcome = new TiXmlElement(_T("Welcome"));
if (NULL==pWelcome)
{
return false;
}
pMsg->LinkEndChild(pWelcome);
// 设置Welcome节点的值
std::string strValue = _T("Welcome to MyApp");
TiXmlText *pWelcomeValue = new TiXmlText(strValue);
pWelcome->LinkEndChild(pWelcomeValue);
// 生成子节点:Farewell
TiXmlElement *pFarewell = new TiXmlElement(_T("Farewell"));
if (NULL==pFarewell)
{
return false;
}
pMsg->LinkEndChild(pFarewell);
// 设置Farewell节点的值
strValue = _T("Thank you for using MyApp");
TiXmlText *pFarewellValue = new TiXmlText(strValue);
pFarewell->LinkEndChild(pFarewellValue);
// 生成子节点:Windows
TiXmlElement *pWindows = new TiXmlElement(_T("Windows"));
if (NULL==pWindows)
{
return false;
}
pRootEle->LinkEndChild(pWindows);
// 生成子节点:Window
TiXmlElement *pWindow = new TiXmlElement(_T("Window"));
if (NULL==pWindow)
{
return false;
}
pWindows->LinkEndChild(pWindow);
// 设置节点Window的值
pWindow->SetAttribute(_T("name"),_T("MainFrame"));
pWindow->SetAttribute(_T("x"),_T("5"));
pWindow->SetAttribute(_T("y"),_T("15"));
pWindow->SetAttribute(_T("w"),_T("400"));
pWindow->SetAttribute(_T("h"),_T("250"));
// 生成子节点:Window
TiXmlElement *pConnection = new TiXmlElement(_T("Connection"));
if (NULL==pConnection)
{
return false;
}
pRootEle->LinkEndChild(pConnection);
// 设置节点Connection的值
pConnection->SetAttribute(_T("ip"),_T("192.168.0.1"));
pConnection->SetAttribute(_T("timeout"),_T("123.456000"));
pDoc->SaveFile(XmlFile);
return true;
}
不知你注意到上面的规律没有?首先父节点连接字节点使用函数LinkEndChild,使用方法是:pParentNode-> LinkEndChild(pChild);其次设置类似这种结构<Window name="MainFrame" x="5" y="15" w="400" h="250" />采用SetAttribute函数,这个函数有两个参数,前一个参数表示键,后一个参数表示键值,设置<Farewell>Thank you for using MyApp</Farewell>这种结构采用TiXmlText类,使用LinkEndChild函数进行连结。
上面是创建xml文件的代码,下面介绍读取xml文件的代码。打印整个xml文件的代码很简单,代码如下:
/*!
* brief 打印xml文件。
*
* param XmlFile xml文件全路径。
* return 是否成功。true为成功,false表示失败。
*/
bool PaintXml(std::string XmlFile)
{
// 定义一个TiXmlDocument类指针
TiXmlDocument *pDoc = new TiXmlDocument();
if (NULL==pDoc)
{
return false;
}
pDoc->LoadFile(XmlFile);
pDoc->Print();
return true;
}
下次介绍使用tinyxml库对xml文件进行查询指定节点、删除指定节点、修改指定节点和增加节点的用法。
参考文献:
1.《TinyXML入门教程》
2. 《tinyxml 使用笔记与总结》
3. 《TinyXML Tutorial 中文指南》
4. 《使用TinyXml解析Xml示例》