您的位置:首页 > 编程语言

使用XML解析器(TinyXML)编程

2010-06-01 14:50 239 查看
参考http://www.cppblog.com/dyj057/archive/2007/01/26/18007.html
我是在VC下编译运行。
1.首先下载TinyXML库的文件,这里给出链接
http://prdownloads.sourceforge.net/tinyxml/tinyxml_2_3_4.zip?download
2.下载后解压这个压缩包,把所有的东西放到一个找的着的地方(比如,E:\开发库\TinyXML)
3.用Visual C++(推荐VC++.NET2003)创建一个新的工程(Win32控制台)
4.在TinyXML的目录里面找到tinystr.h, tinyxml.h, tinystr.cpp, tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp六个文件加入到刚刚创建的项目中去
5.打开tinyxml.h, 在第一行加入下面这行:
#define TIXML_USE_STL //标志使用STL的内容
6.然后创建一个cpp文件,输入下面的内容:
[align=left]#include "stdafx.h"[/align]
[align=left]#include <iostream>[/align]
[align=left]#include <fstream>[/align]
[align=left]#include "tinyxml.h" [/align]
[align=left]using namespace std;[/align]
[align=left] [/align]
[align=left]int _tmain(int argc, _TCHAR* argv[])[/align]
[align=left]{[/align]
[align=left]//原先代码是直接加载XML文件,我作了一下修改,把内容读到字符串后再解析,实际使用时就去掉读取XML文件这一步[/align]
[align=left]string filename = "first.xml";[/align]
[align=left]//TiXmlDocument* doc = new TiXmlDocument(filename.c_str()); [/align]
[align=left] //////////////////////////////////////////////////////////////////////////[/align]
[align=left]// 在这里复制文件[/align]
[align=left]//////////////////////////////////////////////////////////////////////////[/align]
[align=left]std::ifstream ifs(filename.c_str());[/align]
[align=left]char buffer[1024];[/align]
[align=left]char c, *p = buffer;[/align]
[align=left]while(ifs.get(c))[/align]
[align=left]{[/align]
[align=left] *p++=c;[/align]
[align=left]}[/align]
[align=left]*p = 0;[/align]
[align=left]ifs.close();[/align]
[align=left]////////////////////////////////////////////////////////////////////////// [/align]
[align=left] [/align]
[align=left]//这里开始从字符串中解析XML[/align]
[align=left]//创建TiXmlDocument对象[/align]
[align=left]TiXmlDocument* doc = new TiXmlDocument(); [/align]
[align=left]//解析[/align]
[align=left]if(!doc->Parse(buffer))[/align]
[align=left]{[/align]
[align=left] cout << doc->ErrorDesc() << endl;[/align]
[align=left]} [/align]
[align=left]//获取根节点[/align]
[align=left]const TiXmlElement* root = doc->RootElement();[/align]
[align=left]//循环获取该根节点下面的节点[/align]
[align=left]for( const TiXmlNode* child = root->FirstChild();[/align]
[align=left] child;[/align]
[align=left] child=child->NextSibling())[/align]
[align=left]{[/align]
[align=left] //判断为元素类型并且是staticbox元素,Value()获取该标签的名称[/align]
[align=left] if((child->Type() == TiXmlNode::ELEMENT) && (!strcmp(child->Value(),"staticbox")))[/align]
[align=left] {[/align]
[align=left] const TiXmlElement *box = (const TiXmlElement*)child; [/align]
[align=left] [/align]
[align=left] double px, py, pz;[/align]
[align=left] double dx, dy, dz; [/align]
[align=left] [/align]
[align=left] //获取属性值[/align]
[align=left] std::string mesh;[/align]
[align=left] mesh = box->Attribute("mesh"); [/align]
[align=left] //继续循环获取子节点相关数据[/align]
[align=left] for(const TiXmlNode *sub_tag = box->FirstChild(); sub_tag; sub_tag = sub_tag->NextSibling() )[/align]
[align=left] {[/align]
[align=left] if(sub_tag->Type() == TiXmlNode::ELEMENT)[/align]
[align=left] {[/align]
[align=left] const TiXmlElement *sub_element = (const TiXmlElement*)sub_tag; [/align]
[align=left] [/align]
[align=left] if(!strcmp(sub_tag->Value(),"position"))[/align]
[align=left] {[/align]
[align=left] px = (sub_element->Attribute("x",&px))?px:0.0;[/align]
[align=left] py = (sub_element->Attribute("y",&py))?py:0.0;[/align]
[align=left] pz = (sub_element->Attribute("z",&pz))?pz:0.0;[/align]
[align=left] }[/align]
[align=left] else if(!strcmp(sub_tag->Value(),"dimension"))[/align]
[align=left] {[/align]
[align=left] dx = (sub_element->Attribute("x",&dx))?dx:1.0;[/align]
[align=left] dy = (sub_element->Attribute("y",&dy))?dy:1.0;[/align]
[align=left] dz = (sub_element->Attribute("z",&dz))?dz:1.0;[/align]
[align=left] }[/align]
[align=left]else if(!strcmp(sub_tag->Value(),"test"))[/align]
[align=left] {[/align]
[align=left] //使用GetText()方法来获取该标签的值,如这里获取的是test的值1和2[/align]
[align=left] string temp = sub_element->GetText();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] } [/align]
[align=left] [/align]
[align=left] cout << "<StaticBox>\n";[/align]
[align=left] cout << "\tPosition = (" << px << ", " << py << ", " << pz << ")\n";[/align]
[align=left] cout << "\tDimension = (" << dx << ", " << dy << ", " << dz << ")\n\n";[/align]
[align=left] }[/align]
[align=left]} [/align]
[align=left] [/align]
[align=left]delete doc; [/align]
[align=left]getchar();[/align]
[align=left] return 0;[/align]
[align=left]}[/align]
7.然后在项目的文件夹中加入一个xml文件,如下:
[align=left]<?xml version="1.0" encoding="utf-8" ?>[/align]
[align=left]<Scene>[/align]
[align=left]<staticbox mesh="crate.mesh">[/align]
[align=left] <position x="-8" y="2" z="4" />[/align]
[align=left] <dimension x="2" y="4" z="2" />[/align]
[align=left] <test>1</test>[/align]
[align=left]</staticbox>[/align]
[align=left]<staticbox mesh="crate.mesh">[/align]
[align=left] <position x="3" y="2" z="4" />[/align]
[align=left] <dimension x="2" y="4" z="2" />[/align]
[align=left] <test>2</test>[/align]
[align=left]</staticbox>[/align]
[align=left]</Scene>[/align]
[align=left]8.编译运行[/align]

附另一个TinyXML读写XML的例子,此处写XML是直接写入XML文件,如果要使用这里的函数不写入文件而是组织成XML流,需要相应修改代码。代码在VS2005中测试运行成功。
[align=left]#define TIXML_USE_STL //标志使用STL的内容[/align]
[align=left] [/align]
[align=left]#include "stdafx.h"[/align]
[align=left]#include <iostream>[/align]
[align=left]#include <sstream>[/align]
[align=left]#include <fstream>[/align]
[align=left]#include "tinyxml.h" [/align]
[align=left]using namespace std;[/align]
[align=left] [/align]
[align=left]int WriteXML() ;[/align]
[align=left]int ReadXML() ;[/align]
[align=left]//读取内存里的一段XML[/align]
[align=left]int ReadXML2() ;[/align]
[align=left] [/align]
[align=left]int _tmain(int argc, _TCHAR* argv[])[/align]
[align=left]{[/align]
[align=left] [/align]
[align=left] cout << "开始测试!" <<endl;[/align]
[align=left] [/align]
[align=left] WriteXML() ;[/align]
[align=left] ReadXML() ;[/align]
[align=left] ReadXML2() ;[/align]
[align=left] cout << "结束测试!" << endl ;[/align]
[align=left] [/align]
[align=left] return 0;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]int WriteXML()[/align]
[align=left]{[/align]
[align=left] TiXmlDocument xmlDoc( "test.xml" ); // 建立一个XML文件[/align]
[align=left] [/align]
[align=left] TiXmlDeclaration Declaration( "1.0","gb2312", "yes" ); // 声明XML的属性[/align]
[align=left] [/align]
[align=left] xmlDoc.InsertEndChild( Declaration ); // 写入基本的XML头结构 [/align]
[align=left] [/align]
[align=left] TiXmlNode * pNode = NULL; [/align]
[align=left] TiXmlElement* pRootElm = NULL; [/align]
[align=left] TiXmlElement* pChildeElm = NULL; [/align]
[align=left] TiXmlElement* pItemElm = NULL; [/align]
[align=left] TiXmlText* pText = NULL; // 一个指向Text的指针[/align]
[align=left] pText = new TiXmlText("good") ;[/align]
[align=left] [/align]
[align=left] pRootElm = new TiXmlElement( "todo" ); [/align]
[align=left] [/align]
[align=left] pNode = xmlDoc.InsertEndChild(*pRootElm) ;[/align]
[align=left] pRootElm = pNode->ToElement() ;[/align]
[align=left] [/align]
[align=left] pChildeElm = new TiXmlElement("child1") ;[/align]
[align=left] pChildeElm->SetAttribute("num", 9) ;[/align]
[align=left] [/align]
[align=left] pNode = pRootElm->InsertEndChild(*pChildeElm) ;[/align]
[align=left] TiXmlElement* pChildeElm1 = NULL; [/align]
[align=left] pChildeElm1 = pNode->ToElement() ;[/align]
[align=left] pChildeElm1->InsertEndChild(*pText) ;[/align]
[align=left] [/align]
[align=left] delete pChildeElm ;[/align]
[align=left] pChildeElm = NULL ;[/align]
[align=left] pChildeElm = new TiXmlElement("child2") ;[/align]
[align=left] pChildeElm->SetAttribute("num", 10) ;[/align]
[align=left] [/align]
[align=left] pNode = pRootElm->InsertBeforeChild (pChildeElm1, *pChildeElm) ;[/align]
[align=left] TiXmlElement* pChildeElm2 = NULL; [/align]
[align=left] pChildeElm2 = pNode->ToElement() ;[/align]
[align=left] pChildeElm2->InsertEndChild(*pText) ;[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] xmlDoc.Print() ;[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] xmlDoc.SaveFile(); // 把XML文件写入硬盘[/align]
[align=left] [/align]
[align=left] return 0 ;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]int ReadXML()[/align]
[align=left]{[/align]
[align=left] cout<<endl ;[/align]
[align=left] cout<<"开始read XML"<<endl ;[/align]
[align=left] TiXmlDocument xmlDoc( "test.xml" );[/align]
[align=left] xmlDoc.LoadFile() ;[/align]
[align=left] [/align]
[align=left] TiXmlElement* xmlRootElement = 0 ;[/align]
[align=left] TiXmlElement* xmlSubElement = 0 ;[/align]
[align=left] TiXmlNode * pNode = NULL; [/align]
[align=left] [/align]
[align=left] pNode = xmlDoc.FirstChild("todo") ;[/align]
[align=left] xmlRootElement = pNode->ToElement() ;[/align]
[align=left] [/align]
[align=left] if(xmlRootElement)[/align]
[align=left] {[/align]
[align=left] pNode = xmlRootElement->FirstChild("child1") ;[/align]
[align=left] xmlSubElement = pNode->ToElement() ;[/align]
[align=left] cout<<xmlSubElement->Value()<<endl ;[/align]
[align=left] cout<<xmlSubElement->Attribute("num")<<endl ;[/align]
[align=left] cout<<xmlSubElement->GetText()<<endl ;[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] cout<<"找不到根元素"<<endl ;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] cout<<"结束read XML"<<endl ;[/align]
[align=left] return 0 ;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]int ReadXML2()[/align]
[align=left]{[/align]
[align=left] cout<<endl ;[/align]
[align=left] cout<<"开始read XML"<<endl;[/align]
[align=left] const char* demoEnd ="<?xml version=\"1.0\" encoding=\"gb2312\" standalone=\"yes\" ?>"[/align]
[align=left] "<todo>"[/align]
[align=left] "<child2 num=\"10\">good</child2>"[/align]
[align=left] "<child1 num=\"9\">good</child1>"[/align]
[align=left] "</todo>" ;[/align]
[align=left] TiXmlDocument xmlDoc;[/align]
[align=left] [/align]
[align=left] xmlDoc.Parse( demoEnd ) ;[/align]
[align=left] [/align]
[align=left] TiXmlElement* xmlRootElement = 0 ;[/align]
[align=left] TiXmlElement* xmlSubElement = 0 ;[/align]
[align=left] TiXmlNode * pNode = NULL; [/align]
[align=left] [/align]
[align=left] pNode = xmlDoc.FirstChild("todo") ;[/align]
[align=left] xmlRootElement = pNode->ToElement() ;[/align]
[align=left] [/align]
[align=left] if(xmlRootElement)[/align]
[align=left] {[/align]
[align=left] pNode = xmlRootElement->FirstChild("child1") ;[/align]
[align=left] xmlSubElement = pNode->ToElement() ;[/align]
[align=left] cout<<xmlSubElement->Value()<<endl ;[/align]
[align=left] cout<<xmlSubElement->Attribute("num")<<endl ;[/align]
[align=left] cout<<xmlSubElement->GetText()<<endl ;[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] cout<<"找不到根元素"<<endl ;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] cout<<"结束read XML"<<endl ;[/align]
[align=left] return 0 ;[/align]
}
//----------------------------mycode--------------------------------//
private:
template <class T>
static T * _tinyxmlparser(const TiXmlElement *_element,T *_fieldsptr);

public:
static void * xmlparser(const string &xmlStream,int layers=1);

//---------------------------------cpp----------------------------------//

template <class T>
T * Util::_tinyxmlparser(const TiXmlElement *_element,T *_fieldsptr)
{
const TiXmlNode *child = _element->FirstChild();
if (!child || child->Type() != TiXmlNode::ELEMENT)
{
string str_value = _element->GetText()==NULL?"":_element->GetText();
_fieldsptr->insert(typename T::value_type(_element->Value(),str_value));
}
else
{
for(const TiXmlElement *sub_tag =_element->FirstChildElement(); sub_tag; sub_tag = sub_tag->NextSiblingElement())
{
_tinyxmlparser(sub_tag,_fieldsptr);
}
}
return _fieldsptr;
}

void * Util::xmlparser(const std::string &xmlStream,int layers)
{
try
{
//创建TiXmlDocument对象
TiXmlDocument doc;// = TiXmlDocument;
//解析
const char *buffer = xmlStream.c_str();
if(!doc.Parse(buffer))
{
throw MyError("xml_error.log",doc.ErrorDesc());
}
//获取根节点
const TiXmlElement* root = doc.RootElement();
switch(layers)
{
case 1:
{
fields_t * _fields = new map<string,string>;
_tinyxmlparser(root,_fields);
return _fields;
}
break;
default:
{
multimap<string,string> * _fields = new multimap<string,string>;
_tinyxmlparser(root,_fields);
return _fields;
}
break;
}

}
catch(...)
{
return NULL;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: