6.ACE 解析xml

前端之家收集整理的这篇文章主要介绍了6.ACE 解析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文件后的数据会保存在这个类的实例里面。

通过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_; };
回到顶部 xml_parser完整代码展示
#include ACEXML/common/FileCharStream.h" #include ACEXML/parser/parser/Parser.h" 对xml文件进行解析的类,将解析后的数据保存的格式依赖于HANDLER类 HANDLER 必须继承自ACEXML_DefaultHandler类,并且提供"string path();"这样的方法 注意:此对象不提供多进程或多线程按序访问的功能 template< typename HANDLER> class xml_parser { static bool parse(HANDLER& handler) { ACEXML_FileCharStream* fstm = new(std::nothrow)ACEXML_FileCharStream(); if(!fstm) { false; } string path = handler.path(); if(path.empty()) { false; } fstm->open(path.c_str()); ACEXML_InputSource类的析构方法中会通过“delete fstm”来释放内存 ACEXML_InputSource input(fstm); ACEXML_Parser parser; parser.setContentHandler(&handler); parser.setDTDHandler(&handler); parser.setEntityResolver(&handler); parser.setErrorHandler(&handler); try { parser.parse(&input); } catch(const ACEXML_Exception* ex) { ex->print(); catch(std::bad_alloc& ex) { true; } };

猜你在找的XML相关文章