6.ACE 解析xml
发布时间:2020-12-16 06:29:10 所属栏目:百科 来源:网络整理
导读:ACEXML解析XML文件——简单示例程序 阅读目录 定义基本结构 xml_hanlder主要方法介绍 xml_handler完整代码展示 xml_parser完整代码展示 调用代码展示 源代码下载 系列链接 掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序。 回到顶部 定义
ACEXML解析XML文件——简单示例程序阅读目录
掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序。
回到顶部
定义基本结构xml文件格式如下
Collapse
<?xml version="1.0"?> <root version="9" count="3" > file id="1">D:test1.txt</file="2">D:test2.txt="3">D:test3.txt> root> 这个xml文件虽然短小,但是对于示例程序来说已经足够了。 xml文件解析后,要将解析的数据保存起来,可以定义这样两个结构: //对应xml文件的根节点
typedef struct _ROOT
{
版本号
int version;
子项的数量
int count;
} ROOT;
对应xml文件的子项
typedef struct _FILE
{
int id;
文件路径
string path;
} ROOT_FILE;
通过宏定义来指定每个节点的名字: Collapse
#define XML_ROOT "root" #define XML_FILE "file" #define XML_ID "id" #define XML_VER "version" #define XML_COUNT "count" 定义并实现两个类xml_handler、xml_parser。 xml_parser负责解析xml文件,但是它并不关心xml文件中的数据按什么样的格式保存。 而和具体的格式相关的类为xml_handler,解析xml文件后的数据会保存在这个类的实例里面。
回到顶部
xml_hanlder主要方法介绍
通过startElement和characters两个方法来获取数据: virtual void startElement( const ACEXML_Char *namespaceURI,const ACEXML_Char *localName,255)">const ACEXML_Char *qName,ACEXML_Attributes *atts )
{
file节点
if(stricmp(localName,XML_FILE) == 0)
{
if(root_.count == files_.size())
{
return;
}
flag_ = FLAG_FILE;
ROOT_FILE* file = new ROOT_FILE();
files_.push_back(file);
for(int i=0; i<atts->getLength(); ++i)
{
const char* qname = atts->getQName(i);
if(stricmp(qname,XML_ID) == 0)
{
file->id = atoi(atts->getValue(i));
}
}
}
root节点
else 0)
{
flag_ = FLAG_ROOT;
0)
{
root_.version= atoi(atts->getValue(i));
}
0)
{
root_.count = atoi(atts->getValue(i));
}
}
}
}
void characters( const ACEXML_Char *ch,size_t start,size_t length )
{
if(flag_ == FLAG_FILE)
{
files_[files_.size() - 1]->path = ch;
}
flag_ = FLAG_NULL;
}
通过flush方法将root、file信息写入到xml文件中: 将当前root、file信息写入到xml文件中
bool flush() const
{
ofstream ofs(filepath_.c_str(),ios_base::trunc);
if(!ofs)
{
return false;
}
ofs << "<?xml version="1.0"?>" << endl;
ofs << <" << XML_ROOT << " " << XML_VER << ="" << root_.version << " " << XML_COUNT << " << root_.count << " >" << endl;
for(size_t i=0; i<files_.size(); ++i)
{
ofs << t<" << XML_FILE << " << XML_ID << " << files_[i]->id << " << files_[i]->path << </>" << endl;
}
ofs << " << endl;
ofs.close();
true;
}
通过重载操作符operator[]方法获得子项的数据: 获取第index个ROOT_FILE子项
如果index超出当前子项的个数,则返回0
const ROOT_FILE* operator[](size_t index) const
{
if(index >= files_.size())
{
return 0;
}
return files_[index];
}
回到顶部
xml_handler完整代码展示
#pragma once
#include ACEXML/common/DefaultHandler.h"
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
string path;
} ROOT_FILE;
#define XML_COUNT "count"
针对某个具体的xml文件格式进行解析的类
注意:此对象不提供多进程或多线程按序访问的功能
class xml_handler : public ACEXML_DefaultHandler
{
public:
构造。
@param name 字符串,输入,xml文件的路径
xml_handler(char* path): filepath_(path),flag_(0) {}
virtual ~xml_handler(){
0; i<files_.size(); ++i)
{
if(files_[i])
{
delete files_[i];
files_[i] = 0;
}
}
files_.clear();
}
获取xml文件的路径
string& path() const
{
return filepath_;
}
获取子项的数量,对应root.count
const size_t count() return files_.size();
}
获取第index个ROOT_FILE子项
如果index超出当前子项的个数,则返回0
if(index >= files_.size())
{
0;
}
return files_[index];
}
获取root信息
const ROOT& root() return root_;
}
增加一个子项
@param path 字符串,输入,文件的路径
@param id 整形,输入,文件id
bool increase(char* path,size_t id)
{
if(!path || *path == 0 || id == 0)
{
false;
}
ROOT_FILE* file = new(std::nothrow)ROOT_FILE();
申请内存失败
if(!file)
{
false;
}
file->path = path;
file->id = id;
files_.push_back(file);
true;
}
将当前root、file信息写入到xml文件中
const
{
ofstream ofs(filepath_.c_str(),ios_base::trunc);
if(!ofs)
{
false;
}
ofs << " << endl;
ofs << " << endl;
0; i<files_.size(); ++i)
{
ofs << " << endl;
}
ofs << " << endl;
ofs.close();
将当前root、file信息输出到控制台
void dump() const
{
cout << " << endl;
cout << 0; i<files_.size(); ++i)
{
cout << " << endl;
}
cout << " << endl;
}
public:
if(flag_ == FLAG_FILE)
{
files_[files_.size() - 1]->path = ch;
}
flag_ = FLAG_NULL;
}
void endDocument( void )
{
}
void endElement( const ACEXML_Char *qName )
{
}
void endPrefixMapping( const ACEXML_Char *prefix )
{
}
void ignorableWhitespace( const ACEXML_Char *ch,255)">int start,255)">int length )
{
}
void processingInstruction( const ACEXML_Char *target,255)">const ACEXML_Char *data )
{
}
void setDocumentLocator( ACEXML_Locator *locator )
{
locator_ = locator;
}
void skippedEntity( const ACEXML_Char *name )
{
}
void startDocument( atts )
{
file节点
if(root_.count == files_.size())
{
return;
}
flag_ = FLAG_FILE;
ROOT_FILE* file = new ROOT_FILE();
files_.push_back(file);
0; i<atts->getLength(); ++i)
{
char* qname = atts->getQName(i);
0)
{
file->id = atoi(atts->getValue(i));
}
}
}
root节点
0)
{
flag_ = FLAG_ROOT;
0)
{
root_.version= atoi(atts->getValue(i));
}
0)
{
root_.count = atoi(atts->getValue(i));
}
}
}
}
void startPrefixMapping( const ACEXML_Char *prefix,255)">const ACEXML_Char *uri )
{
}
void notationDecl( const ACEXML_Char *name,255)">const ACEXML_Char *publicId,255)">const ACEXML_Char *systemId )
{
}
void unparsedEntityDecl( const ACEXML_Char *systemId,255)">const ACEXML_Char *notationName )
{
}
virtual ACEXML_InputSource * resolveEntity( const ACEXML_Char *systemId )
{
0;
}
void error( ACEXML_SAXParseException &exception )
{
}
void fatalError( ACEXML_SAXParseException &exception )
{
}
void warning( ACEXML_SAXParseException &exception )
{
}
private:
xml文件路径
string filepath_;
ACEXML_Locator* locator_;
ROOT root_;
vector<ROOT_FILE*> files_;
enum FLAG
{
FLAG_NULL,FLAG_ROOT,FLAG_FILE,};
int flag_;
};
|