TinyXML封装与测试(转)

Advertisement

最近在写关于XML配置文件读写的程序,用的是开源的TinyXML解析工具,如果直接使用的话,不是很方便,会产生大量的重复的代码,因此将其进行封装(Facade模式),便于程序的书写。
程序目录:

下面是:封装代码和测试代码:
XML.h


#pragma once
#pragma once
#include<string>
#include <iostream>
#include "../TinyXMLSource/tinyxml.h"
using namespace std;
class CXML
{
public:
CXML(void);
~CXML(void);
bool ParseXmlFile(const char* xmlFile);
void Clear();
void SaveFile(const char* file);
//////////////////////////////////////////////////////////////////////////
TiXmlElement * GetRootElement();
TiXmlElement * GetChildElement(TiXmlElement * pParentElement,const char * title);
TiXmlElement * GetFirstChildElement(TiXmlElement * pParentElement);
TiXmlElement * GetNextChildElement(TiXmlElement * pElement);
//////////////////////////////////////////////////////////////////////////
TiXmlElement * FindFirstElement(const char * title);//递归查找
//////////////////////////////////////////////////////////////////////////
std::string GetElementValue(TiXmlElement * pElement);
std::string GetElementAttributeValue(TiXmlElement* Element,const char* AttributeName);
std::string GetChildElementValue(TiXmlElement * pParentElement,const char * title);
std::string GetChildElementAttributeValue(TiXmlElement * pParentElement,const char *title,const char* AttributeName);
//////////////////////////////////////////////////////////////////////////
TiXmlElement* AddXmlRootElement(const char* title);
TiXmlElement* AddXmlChildElement(TiXmlElement* pPareElement,const char* title,constchar * value = "\0");
void AddXmlAttribute(TiXmlElement* pElement,const char* name,const char* value);
void AddXmlDeclaration(const char* vesion="1.0",const char* encoding="gb2312",constchar* standalone="");
void AddElementValue(TiXmlElement * pElement,const char* value);
void AddXmlComment(TiXmlElement* pElement,const char* Comment);
//////////////////////////////////////////////////////////////////////////
bool ReplaceElementValue(TiXmlElement * pElement,const char * newValue);
bool ReplaceElementAttribute(TiXmlElement* pElement,const char * name,const char *newValue);
//////////////////////////////////////////////////////////////////////////
private:
TiXmlElement * FindFirstElement(TiXmlElement* pcrElement,const char * title);//递归查找

private:
TiXmlDocument m_xml;
};

XML.cpp


#include "xml.h"
CXML::CXML(void)
{

}
CXML::~CXML(void)
{

}
bool CXML::ParseXmlFile(const char* xmlFile)
{
m_xml.LoadFile(xmlFile);
if (m_xml.Error())
{
int nError = m_xml.ErrorId();
std::cout<<m_xml.ErrorDesc();
return false;
}
return true;
}
TiXmlElement* CXML::GetRootElement()
{
return m_xml.RootElement();
}
TiXmlElement * CXML::GetChildElement(TiXmlElement * pParentElement,const char * title)
{
if (pParentElement != NULL)
{
TiXmlNode * childNode = GetFirstChildElement(pParentElement);
for (;childNode;childNode = GetNextChildElement(childNode->ToElement()))
{
if (!strcmp(title,childNode->Value()))
{
return childNode->ToElement();
}
}
}
return NULL;
}
TiXmlElement * CXML::GetFirstChildElement(TiXmlElement * pParentElement)
{
if (pParentElement != NULL)
{
TiXmlElement * child = pParentElement->FirstChildElement();
return child;
}
return NULL;
}
TiXmlElement * CXML::GetNextChildElement(TiXmlElement * pElement)
{
if (pElement)
{
TiXmlElement * nextChild = pElement->NextSiblingElement();
return nextChild;
}
return NULL;
}
std::string CXML::GetElementValue(TiXmlElement * Element)
{
std::string reslut = "\0";
if (Element != NULL)
{
reslut = Element->GetText();
}
return reslut;
}
std::string CXML::GetElementAttributeValue(TiXmlElement* Element,const char*AttributeName)
{
std::string reslut = "\0";
if (Element != NULL)
{
reslut = Element->Attribute(AttributeName);
}
return reslut;
}
std::string CXML::GetChildElementValue(TiXmlElement * pParentElement,const char * title)
{
std::string reslut = "\0";
TiXmlElement * pElem = GetChildElement(pParentElement,title);
reslut = GetElementValue(pElem);
return reslut;
}
std::string CXML::GetChildElementAttributeValue(TiXmlElement * pParentElement,const char *title,const char* AttributeName)
{
std::string reslut = "\0";
TiXmlElement * pElem = GetChildElement(pParentElement,title);
reslut = GetElementAttributeValue(pElem,AttributeName);
return reslut;
}
void CXML::Clear()
{
m_xml.Clear();
}
//////////////////////////////////////////////////////////////////////////
TiXmlElement* CXML::AddXmlRootElement(const char* title)
{
TiXmlElement* element =new TiXmlElement(title);
m_xml.LinkEndChild(element);
return element;
}
TiXmlElement* CXML::AddXmlChildElement(TiXmlElement* pPareElement,const char* title,constchar * value)
{
if(pPareElement)
{
TiXmlElement* childElem =new TiXmlElement(title);
pPareElement->LinkEndChild(childElem);
if (value != "\0")
{
AddElementValue(childElem,value);
}
return childElem;
}
return 0;
}
void CXML::AddXmlAttribute(TiXmlElement* pElement,const char* name,const char* value)
{
if(pElement)
{
pElement->SetAttribute(name,value);
}
}
void CXML::AddXmlDeclaration(const char* vesion,const char* encoding,const char*standalone)
{
TiXmlDeclaration * decl =new TiXmlDeclaration(vesion,encoding,standalone);
m_xml.LinkEndChild(decl);
}

void CXML::AddElementValue(TiXmlElement *pElement,const char* value)
{
if(pElement)
{
TiXmlText * text =new TiXmlText(value);
pElement->LinkEndChild(text);
}
}

void CXML::AddXmlComment(TiXmlElement* pElement,const char* Comment)
{
if(pElement)
{
TiXmlComment * comment =new TiXmlComment(Comment);
pElement->LinkEndChild(comment);
}
}

bool CXML::ReplaceElementValue(TiXmlElement* pElement,const char * newValue)
{
if (pElement != NULL)
{
TiXmlNode * oldNode = NULL;
oldNode = pElement->FirstChild();
if (oldNode != NULL)
{
TiXmlText newText(newValue);
pElement->ReplaceChild(oldNode,newText);
return true;
}
}
return false;
}

bool CXML::ReplaceElementAttribute(TiXmlElement* pElement,const char * name,const char *newValue)
{
if (pElement != NULL)
{
TiXmlAttribute * oldAttribute = NULL;
oldAttribute = pElement->FirstAttribute();
for(;oldAttribute != NULL;oldAttribute = oldAttribute->Next())
{
if (!strcmp(name,oldAttribute->Name()))
{
oldAttribute->SetValue(newValue);
}
}
}
return false;
}

void CXML::SaveFile(const char* file)
{
m_xml.SaveFile(file);
}

TiXmlElement * CXML::FindFirstElement(const char * title)
{
if(!title)
return 0;
TiXmlElement * pElem = NULL;
pElem = GetRootElement();
pElem = FindFirstElement(pElem,title);
return pElem;
}

TiXmlElement * CXML::FindFirstElement(TiXmlElement* pcrElement,const char * title)
{
TiXmlNode * pNode = pcrElement;
while(pNode)
{
if(strcmp(pNode->Value(),title)==0)
{
return pNode->ToElement();
}
else
{
TiXmlNode * nextElement= pNode->FirstChildElement();
while(nextElement)
{
if(strcmp(nextElement->Value(),title)==0)
{
return nextElement->ToElement();
}
else
{
TiXmlElement* reElement = NULL;
reElement = FindFirstElement(nextElement->ToElement(),title);
if(reElement)
{
return reElement;
}
}
nextElement = nextElement->NextSiblingElement();
}
}
pNode = pNode->NextSiblingElement();
}
return NULL;
}

Test.cpp


#include <iostream>
#include "../XMLFacade/XML.h"

void LoadXML()
{
CXML xml;
std::string result;
xml.ParseXmlFile("ServerConfig.xml");
TiXmlElement * pParentElem, *pElement;
//////////////////////////////////////////////////////////////////////////
std::cout<<"测试一:顺序遍历查找:"<<std::endl;
pParentElem = xml.GetRootElement();
std::cout<<"ServerName:"<<xml.GetChildElementValue(pParentElem,"ServerName").c_str()<<std::endl;
std::cout<<"ServerIP:"<<xml.GetChildElementValue(pParentElem,"ServerIP").c_str()<<std::endl;
std::cout<<"ListenPortID:"<<xml.GetChildElementValue(pParentElem,"ListenPortID").c_str()<<std::endl;
result = xml.GetChildElementAttributeValue(pParentElem,"PortsList","Num");
std::cout<<"PortsList Num:"<<result<<std::endl;
pParentElem = xml.GetChildElement(pParentElem,"PortsList");
pElement = xml.GetFirstChildElement(pParentElem);
while(pElement)
{
std::cout<<"================================================================="<<std::endl;
std::cout<<"Port:"<<std::endl;
std::cout<<"PortID:"<<xml.GetChildElementValue(pElement,"PortID").c_str()<<std::endl;
std::cout<<"MaxConnection:"<<xml.GetChildElementValue(pElement,"MaxConnection").c_str()<<std::endl;
pElement = xml.GetNextChildElement(pElement);
}
//////////////////////////////////////////////////////////////////////////
std::cout<<"测试二:递归遍历查找:"<<std::endl;
pElement = xml.FindFirstElement("Port");
while(pElement)
{
std::cout<<"================================================================="<<std::endl;
std::cout<<"Port:"<<std::endl;
std::cout<<"PortID:"<<xml.GetChildElementValue(pElement,"PortID").c_str()<<std::endl;
std::cout<<"MaxConnection:"<<xml.GetChildElementValue(pElement,"MaxConnection").c_str()<<std::endl;
pElement = xml.GetNextChildElement(pElement);
}
//////////////////////////////////////////////////////////////////////////
std::cout<<"测试三:替换:"<<std::endl;
pElement = xml.FindFirstElement("ServerName");
xml.ReplaceElementValue(pElement,"新服务器");
std::cout<<"ServerName:"<<xml.GetElementValue(pElement).c_str()<<std::endl;
pElement = xml.FindFirstElement("PortsList");
xml.ReplaceElementAttribute(pElement,"Num","10");
std::cout<<"PortsList Num:"<<xml.GetElementAttributeValue(pElement,"Num").c_str()<<std::endl;
}

void CreateXML()
{
CXML xml;
xml.AddXmlDeclaration();
TiXmlElement* root = xml.AddXmlRootElement("ServerInfo");
xml.AddXmlComment(root,"服务器配置信息");
TiXmlElement * pElement = xml.AddXmlChildElement(root,"ServerName");
xml.AddElementValue(pElement,"旧服务器");
pElement = xml.AddXmlChildElement(root,"ServerIP");
xml.AddElementValue(pElement,"192.168.14.28");
pElement = xml.AddXmlChildElement(root,"ListenPortID");
xml.AddElementValue(pElement,"8080");
pElement = xml.AddXmlChildElement(root,"PortsList");
xml.AddXmlAttribute(pElement,"Num","5");
root = pElement;
char cPortID[10];
for (int i = 0; i < 5; i++)
{
::memset(cPortID,'\0',10);
::sprintf(cPortID,"%d",20000 + i + 1);
pElement = xml.AddXmlChildElement(root,"Port");
xml.AddXmlChildElement(pElement,"PortID",cPortID);
::sprintf(cPortID,"%d",60);
xml.AddXmlChildElement(pElement,"MaxConnection",cPortID);
}
xml.SaveFile("ServerConfig.xml");
}

int main(int argc, char * argv[])
{
CreateXML();
LoadXML();
getchar();
return 0;
}

程序的输出结果
控制台:




文件:



另外:TinyXML源文件中有一个地方有点问题,可能会导致BUG
就是:
(1)Tinyxml.cpp中的TiXmlElement::Attribute方法


const char* TiXmlElement::Attribute( const char* name ) const
{
const TiXmlAttribute * node = attributeSet.Find(name);
if (node)
return node->Value();
return 0;//应该改成return "\0";
}

(2)Tinyxml.cpp中的TiXmlElement::GetText()方法


const char* TiXmlElement::GetText() const
{
const TiXmlNode * child = this->FirstChild();
if (child)
{
const TiXmlText* childText = child->ToText();
if ( childText ) {
return childText->Value();
}
}
return 0;
//应该改成return "\0";
}

Similar Posts:

  • C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

    在上篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及对应的对象模型,本篇继续微信小店的主题,介绍其中API接口的封装和测试使用.微信小店的相关对象模型,基本上包括了常规的商品.商品分组.货架.库存.订单这些模型,还有商品分类,商品分类属性.商品分类SKU.快递邮寄模板.图片管理等功能.本文介绍的接口封装也就是基于这些内容进行的,并针对接口的实现进行测试和使用. 1.商品管理接口的定义 前面文章介绍了微信小店的对象模型,如下所示. 这个图形基本上覆

  • 第五次作业:封装与测试

    1 1 import java.awt.Dimension; 2 2 import java.awt.FlowLayout; 3 3 import java.awt.GridLayout; 4 4 import java.awt.Toolkit; 5 5 import java.awt.event.ActionEvent; 6 6 import java.awt.event.ActionListener; 7 7 8 8 import javax.swing.JButton; 9 9 impor

  • JSP在数据库中的使用之二:数据库操作的封装与测试

    经常的,我们写的代码不止自己要懂,而且也要方便别人理解,同时,很多对数据库的操作其实是重复的,为了提高代码的可读性和重用性,需要进行封装 所以,接下来,要对JDBC中的常见数据库操作进行封装 1.对数据库的配置信息进行封装 在src下新建属性文件jdbc.properties,如果以后使用其他的数据库,只要在这个文件中进行修改就可以 完成对数据库文件中的一些配置 2.创建一个ConnectionFactory类,用来连接数据库对象 3.创建DBClose.java类,关闭数据库的连接操作,因为查

  • 四则运算,测试与封装。

    测试与封装 5.1 程序开发简介: [开发环境]:eclipse [开发人员]:Ives & 郑胜斌 [博客地址]:http://www.cnblogs.com/IvesHe/ [开发时间]:2015-04-30 [版本]:5.1 [要求]: 封装 测试 [分工]: Ives:单元测试.界面.自定义异常. 郑胜斌:封装 Expression类. 封装: 概念 封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对

  • 自动化测试框架:测试编程框架

    做任何事,要牢记你的用户是谁!设计一个框架,要知道你的用户的使用需求是什么,这样,框架设计才可能容易被接受,离成功也就越进一步了. 框架的用户是测试人员.测试人员的特点是: 熟悉或精通业务 了解程序元素,但不了解程序结构 实现细节更是难以洞察 因此,在设计初期,就考虑将控件的访问封装起来.对于测试人员来说,所有的控件都已经封装好了,他们只需要调用就可以了. 这一点,应该已经初步解决问题了.但是我们并没有满足这一点. 对于测试来讲,他们了解的是业务元素,而我们常规做法,是把控件封装成编程元素.这是

  • 第四部分 开发工具及测试工具

    第四部分 开发工具及测试工具-内容来自互联网 主要介绍和Android开发工具和测试工具相关的开源项目. 一.开发效率工具 Parceler 通过注解及工具类自动完成实体类 Parcelable及值传递 项目地址:https://github.com/johncarl81/parceler Json2Java 根据JSon数据自动生成对应的Java实体类,还支持Parcel.Gson Annotations对应代码自动生成.期待后续的提取父类以及多url构建整个工程的功能 项目地址:https:

  • 芯片设计、制造与封装相关上市公司一览

    (一).芯片设计 DSP 与CPU被公认为芯片工业的两大核心技术.国内CPU产品研发水平最高的以"龙芯"为代表,DSP以"汉芯为代表.专家指出,从2000年开始,我国每年 就使用近100亿元的国外DSP芯片,到2005年前我国DSP市场的需求量在30亿美元以上,年增长将达到40%以上. [1].综艺股份(600770): 公 司参股49%的北京神州龙芯集成电路设计有限公司(和中科院计算技术研究所于02年8月共同设立,注册资本1亿元),从事开发.销售具有自主知识产权的 &quo

  • 如何学习 junit java测试

    为什么要进行单测试. 1. 单元测试的目的 一个单元测试从整个系统中单独检验产品程序代码的『一个单元』并检查其得到的结果是否是预期的.要测试的『一个单元』其大小是依据一组连贯的功能的大小及介于一个类别及一个包(package)之间实际上的变化 (varies).其目的是在整合程序代码到系统的其余部分之前先测试以便找出程序代码中的臭虫(bugs).Junit等支持在Java程序代码中撰写单元测试. 在整合之前于系统其它部分隔离起来抓虫的理由是因为那是比较容易的找到臭虫(亦即比较快且便宜)及比较容易

  • MoleBox Pro 2.6.5 汉化版+封装教程+软件封装

    MoleBox 是一款 对Windows 应用程序在执行时进行打包的工具.他可以把一个应用程序及其需要的所有数据文件打包成一个可执行文件.他也可以用一套数据包创建一个可执行文件就像整合动态链接库到可执行文件中一样.当处理一套应用程序时,MoleBox 压缩并加密可加密的文件.数据.媒体文件和动态链接库.MoleBox能够保护您的应用程序的数据和媒体文件被查看和改动,能够防止您的动态链接库不被第三方程序使用.Molebox 绝不会改变原始应用程序的任何功能,也不需要任何额外的代码.解包和解密(如果

  • 第六章测试架构规划及测试用例组织

    在编写完具体的测试用例后,我们就要组织一下测试用例,这样方便进行回归测试.结合我们的自动化测试的传统,我们继续采取原来的方法来组织我们的测试用例. 6.1 测试架构规划 由于测试用例执行的时候是在手机上执行的,所以类似于Web的把测试数据存放到Xml的方法是不可用的,因为在测试用例运行的时候找不到电脑上存放的xml文件.当然也有手机上数据驱动的方法,见:http://www.cnblogs.com/freeliver54/archive/2011/08/06/2129343.html.测试数据过

Tags: