new XML Parse tools
This commit is contained in:
24
inc/hgl/util/xml/ElementParse.h
Normal file
24
inc/hgl/util/xml/ElementParse.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE
|
||||
#define HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
/**
|
||||
* XML节点解析器
|
||||
*/
|
||||
class ElementParse
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ElementParse()=default;
|
||||
|
||||
virtual bool Start (const char *element_name) {return(true);}
|
||||
virtual void Attr (const char *flag,const char *info) {}
|
||||
virtual void CharData (const char *str,const int str_length) {}
|
||||
virtual void End (const char *element_name) {}
|
||||
};//class ElementParse
|
||||
}//namespace xml
|
||||
}//namespace hgl
|
||||
#endif//HGL_UTIL_XML_ELEMENT_PARSE_INCLUDE
|
73
inc/hgl/util/xml/ElementParseCreater.h
Normal file
73
inc/hgl/util/xml/ElementParseCreater.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE
|
||||
#define HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE
|
||||
|
||||
#include<hgl/util/xml/ElementParse.h>
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/type/Stack.h>
|
||||
#include<hgl/type/Map.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
class ElementCreater
|
||||
{
|
||||
friend class ElementParseCreater;
|
||||
|
||||
AnsiString element_name;
|
||||
|
||||
protected:
|
||||
|
||||
Map<AnsiString,ElementCreater *> ecs_map;
|
||||
|
||||
virtual ElementCreater *GetSubElementCreater(const AnsiString &sub_name);
|
||||
|
||||
public:
|
||||
|
||||
const AnsiString &GetElementName()const{return element_name;}
|
||||
|
||||
public:
|
||||
|
||||
ElementCreater(const AnsiString &en){element_name=en;}
|
||||
virtual ~ElementCreater()=default;
|
||||
|
||||
bool Registry(const AnsiString &name,ElementCreater *ec);
|
||||
|
||||
public:
|
||||
|
||||
virtual bool Start (){return true;}
|
||||
virtual void Attr (const char *flag,const char *info){}
|
||||
virtual void CharData (const char *str,const int str_length){}
|
||||
|
||||
virtual void End (){}
|
||||
};//class ElementCreater
|
||||
|
||||
/**
|
||||
* Creater模式XML节点解析器
|
||||
*/
|
||||
class ElementParseCreater:public ElementParse
|
||||
{
|
||||
Stack<ElementCreater *> ecs_stack;
|
||||
|
||||
ElementCreater *root_ec;
|
||||
ElementCreater *cur_ec;
|
||||
|
||||
public:
|
||||
|
||||
ElementParseCreater(ElementCreater *rec)
|
||||
{
|
||||
root_ec=rec;
|
||||
cur_ec=rec;
|
||||
}
|
||||
|
||||
virtual ~ElementParseCreater()=default;
|
||||
|
||||
public:
|
||||
|
||||
bool Start (const char *element_name) override;
|
||||
void Attr (const char *flag,const char *info) override;
|
||||
void CharData (const char *str,const int str_length) override;
|
||||
void End (const char *element_name) override;
|
||||
};//class ElementParseCreater:public ElementParse
|
||||
}//namespace xml
|
||||
}//namespace hgl
|
||||
#endif//HGL_UTIL_XML_ELEMENT_PARSE_CREATER_INCLUDE
|
64
inc/hgl/util/xml/ElementParseKV.h
Normal file
64
inc/hgl/util/xml/ElementParseKV.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE
|
||||
#define HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE
|
||||
|
||||
#include<hgl/util/xml/ElementParse.h>
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/type/Map.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
/**
|
||||
* KV模式XML节点解析器
|
||||
*/
|
||||
class ElementParseKV:public ElementParse
|
||||
{
|
||||
protected:
|
||||
|
||||
using AttrsMap=Map<AnsiString,AnsiString>;
|
||||
using AttrItem=Pair<AnsiString,AnsiString>;
|
||||
|
||||
AttrsMap attrs_map;
|
||||
|
||||
protected:
|
||||
|
||||
const AttrItem *GetAttrItem(const AnsiString &name);
|
||||
|
||||
template<typename T> const bool GetInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stoi(ai->right.c_str(),value):false);}
|
||||
template<typename T> const bool GetUInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stou(ai->right.c_str(),value):false);}
|
||||
template<typename T> const bool GetFloat (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stof(ai->right.c_str(),value):false);}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ElementParseKV()=default;
|
||||
|
||||
virtual void Attr(const char *flag,const char *info) override;
|
||||
|
||||
public:
|
||||
|
||||
const bool IsExist (const AnsiString &name)const{return attrs_map.KeyExist(name);}
|
||||
|
||||
const char * ToCString (const AnsiString &name){const AttrItem *ai=GetAttrItem(name);return(ai?ai->right.c_str():nullptr);}
|
||||
const char * operator[] (const AnsiString &name){return ToCString(name);}
|
||||
|
||||
public:
|
||||
|
||||
const bool Get(const AnsiString &name,AnsiString &str);
|
||||
const bool Get(const AnsiString &name,UTF16String &str);
|
||||
const bool Get(const AnsiString &name,char &ch);
|
||||
const bool Get(const AnsiString &name,bool &value);
|
||||
|
||||
const bool Get(const AnsiString &name, int8 &value){return GetInteger < int8 >(name,value);}
|
||||
const bool Get(const AnsiString &name,uint8 &value){return GetUInteger<uint8 >(name,value);}
|
||||
const bool Get(const AnsiString &name, int16 &value){return GetInteger < int16>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint16 &value){return GetUInteger<uint16>(name,value);}
|
||||
const bool Get(const AnsiString &name, int32 &value){return GetInteger < int32>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint32 &value){return GetUInteger<uint32>(name,value);}
|
||||
const bool Get(const AnsiString &name, int64 &value){return GetInteger < int64>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint64 &value){return GetUInteger<uint64>(name,value);}
|
||||
|
||||
const bool GetHexStr(const AnsiString &name,uint8 *data);
|
||||
};//class ElementParseKV:public ElementParse
|
||||
}//namespace xml
|
||||
}//namespace hgl
|
||||
#endif//HGL_UTIL_XML_ELEMENT_PARSE_KV_INCLUDE
|
@@ -2,9 +2,7 @@
|
||||
#define HGL_XML_PARSE_INCLUDE
|
||||
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/type/Map.h>
|
||||
#include<hgl/type/StrChar.h>
|
||||
#include<hgl/CodePage.h>
|
||||
#include<hgl/util/xml/ElementParse.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -25,186 +23,89 @@ namespace hgl
|
||||
class InputStream;
|
||||
}//namespace io
|
||||
|
||||
/**
|
||||
* XML节点解析器
|
||||
*/
|
||||
class XMLElementParse
|
||||
namespace xml
|
||||
{
|
||||
public:
|
||||
constexpr int XML_PARSE_BUFFER_SIZE=HGL_SIZE_1KB*128; ///<XML解析缓冲区大小
|
||||
|
||||
virtual bool StartElement(const char *element_name)=0;
|
||||
virtual void Attr(const char *flag,const char *info){};
|
||||
virtual void CharData(const char *str,int str_length){};
|
||||
virtual void EndElement(const char *element_name){};
|
||||
};//class XMLElementParse
|
||||
|
||||
class XMLElementParseKV:public XMLElementParse
|
||||
{
|
||||
protected:
|
||||
|
||||
using AttrsMap=Map<AnsiString,AnsiString>;
|
||||
using AttrItem=Pair<AnsiString,AnsiString>;
|
||||
|
||||
AttrsMap attrs_map;
|
||||
|
||||
protected:
|
||||
|
||||
const AttrItem *GetAttrItem(const AnsiString &name);
|
||||
|
||||
template<typename T> const bool GetInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stoi(ai->right.c_str(),value):false);}
|
||||
template<typename T> const bool GetUInteger (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stou(ai->right.c_str(),value):false);}
|
||||
template<typename T> const bool GetFloat (const AnsiString &name,T &value){const AttrItem *ai=GetAttrItem(name);return(ai?stof(ai->right.c_str(),value):false);}
|
||||
|
||||
public:
|
||||
|
||||
virtual void Attr(const char *flag,const char *info) override;
|
||||
|
||||
public:
|
||||
|
||||
const bool IsExist (const AnsiString &name)const{return attrs_map.KeyExist(name);}
|
||||
|
||||
const char * ToCString (const AnsiString &name){const AttrItem *ai=GetAttrItem(name);return(ai?ai->right.c_str():nullptr);}
|
||||
const char * operator[] (const AnsiString &name){return ToCString(name);}
|
||||
|
||||
public:
|
||||
|
||||
const bool Get(const AnsiString &name,AnsiString &str)
|
||||
/**
|
||||
* XML解析器<br>
|
||||
*/
|
||||
class XMLParse
|
||||
{
|
||||
const AttrItem *ai=GetAttrItem(name);
|
||||
|
||||
if(!ai)return(false);
|
||||
|
||||
str=ai->right;
|
||||
return(true);
|
||||
}
|
||||
protected:
|
||||
|
||||
const bool Get(const AnsiString &name,UTF16String &str)
|
||||
XML_Parser xml;
|
||||
|
||||
int buffer_size;
|
||||
char *buffer;
|
||||
|
||||
protected:
|
||||
|
||||
ElementParse *element_parse;
|
||||
|
||||
virtual void StartParse();
|
||||
|
||||
public:
|
||||
|
||||
XMLParse(ElementParse *,const int size=XML_PARSE_BUFFER_SIZE);
|
||||
virtual ~XMLParse();
|
||||
|
||||
virtual void Start(const char *charset="utf-8");
|
||||
virtual bool Parse(const char *buf,int len,bool isFin);
|
||||
virtual bool Parse(io::InputStream *,bool isFin=true);
|
||||
};//class XMLParse
|
||||
|
||||
bool XMLParseFile(XMLParse *xml,const OSString &filename);
|
||||
|
||||
#define XML_START_PARSE(name) while(*name) \
|
||||
{ \
|
||||
const char *flag=*name;++name; \
|
||||
const char *info=*name;++name;
|
||||
|
||||
#define XML_END_PARSE() LOG_ERROR(UTF8String(__FILE__)+U8_TEXT(":")+UTF8String(__LINE__)+U8_TEXT(" can't parse atts \"")+UTF8String(flag)+U8_TEXT("\" , info \"")+UTF8String(info)+U8_TEXT("\".")); \
|
||||
}
|
||||
#define XML_END_PARSE_SKIP() ;}
|
||||
|
||||
#define xml_parse_skip(name) if(hgl::strcmp(flag,#name)==0)continue;else
|
||||
#define xml_parse_string_u16(name) if(hgl::strcmp(flag,#name)==0)name=to_u16(info);else
|
||||
#define xml_parse_string_u8(name) if(hgl::strcmp(flag,#name)==0)name=info;else
|
||||
#define xml_parse_int(name) if(hgl::strcmp(flag,#name)==0)hgl::stoi(info,name);else
|
||||
#define xml_parse_uint(name) if(hgl::strcmp(flag,#name)==0)hgl::stou(info,name);else
|
||||
#define xml_parse_float(name) if(hgl::strcmp(flag,#name)==0)hgl::stof(info,name);else
|
||||
#define xml_parse_bool(name) if(hgl::strcmp(flag,#name)==0)hgl::stob(info,name);else
|
||||
#define xml_parse_hexstr(name) if(hgl::strcmp(flag,#name)==0)hgl::ParseHexStr(name,info);else
|
||||
|
||||
#define xml_parse_to_string_u8(name,value) if(hgl::strcmp(flag,name)==0)value=info;else
|
||||
#define xml_parse_to_int(name,value) if(hgl::strcmp(flag,name)==0)hgl::stoi(info,value);else
|
||||
#define xml_parse_to_uint(name,value) if(hgl::strcmp(flag,name)==0)hgl::stou(info,value);else
|
||||
#define xml_parse_to_float(name,value) if(hgl::strcmp(flag,name)==0)hgl::stof(info,value);else
|
||||
#define xml_parse_to_bool(name,value) if(hgl::strcmp(flag,name)==0)hgl::stob(info,value);else
|
||||
|
||||
/** 使用范例:
|
||||
|
||||
<root>
|
||||
<role name="Bill" sex="true" age="18"/>
|
||||
<role name="Lucy" sex="false" age="17"/>
|
||||
</root>
|
||||
|
||||
void StartElement(const char *element_name,const char **atts) override
|
||||
{
|
||||
const AttrItem *ai=GetAttrItem(name);
|
||||
|
||||
if(!ai)return(false);
|
||||
|
||||
str=to_u16(ai->right);
|
||||
return(true);
|
||||
if(strcmp(element_name,"role")==0)
|
||||
{
|
||||
std::string name;
|
||||
bool sex;
|
||||
int age;
|
||||
|
||||
XML_START_PARSE(atts)
|
||||
|
||||
xml_parse_string_u8(name)
|
||||
xml_parse_bool(sex)
|
||||
xml_parse_int(age)
|
||||
|
||||
XML_END_PARSE
|
||||
}
|
||||
}
|
||||
|
||||
const bool Get(const AnsiString &name,char &ch)
|
||||
{
|
||||
const AttrItem *ai=GetAttrItem(name);
|
||||
|
||||
if(!ai)return(false);
|
||||
|
||||
ch=ai->right.GetBeginChar();
|
||||
return(true);
|
||||
}
|
||||
|
||||
const bool Get(const AnsiString &name,bool &value)
|
||||
{
|
||||
const AttrItem *ai=GetAttrItem(name);
|
||||
|
||||
return(ai?stob<char>(ai->right.c_str(),value):false);
|
||||
}
|
||||
|
||||
const bool Get(const AnsiString &name, int8 &value){return GetInteger < int8 >(name,value);}
|
||||
const bool Get(const AnsiString &name,uint8 &value){return GetUInteger<uint8 >(name,value);}
|
||||
const bool Get(const AnsiString &name, int16 &value){return GetInteger < int16>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint16 &value){return GetUInteger<uint16>(name,value);}
|
||||
const bool Get(const AnsiString &name, int32 &value){return GetInteger < int32>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint32 &value){return GetUInteger<uint32>(name,value);}
|
||||
const bool Get(const AnsiString &name, int64 &value){return GetInteger < int64>(name,value);}
|
||||
const bool Get(const AnsiString &name,uint64 &value){return GetUInteger<uint64>(name,value);}
|
||||
|
||||
const bool GetHexStr(const AnsiString &name,uint8 *data)
|
||||
{
|
||||
const AttrItem *ai=GetAttrItem(name);
|
||||
|
||||
if(!ai)return(false);
|
||||
|
||||
ParseHexStr(data,ai->right.c_str(),ai->right.Length());
|
||||
return(true);
|
||||
}
|
||||
};//class XMLElementParseKV:public XMLElementParse
|
||||
|
||||
constexpr int XML_PARSE_BUFFER_SIZE=HGL_SIZE_1KB*128; ///<XML解析缓冲区大小
|
||||
|
||||
/**
|
||||
* XML解析器<br>
|
||||
*/
|
||||
class XMLParse
|
||||
{
|
||||
protected:
|
||||
|
||||
XML_Parser xml;
|
||||
|
||||
int buffer_size;
|
||||
char *buffer;
|
||||
|
||||
protected:
|
||||
|
||||
XMLElementParse *element_parse;
|
||||
|
||||
virtual void StartParse();
|
||||
|
||||
public:
|
||||
|
||||
XMLParse(XMLElementParse *,const int size=XML_PARSE_BUFFER_SIZE);
|
||||
virtual ~XMLParse();
|
||||
|
||||
virtual void Start(const char *charset="utf-8");
|
||||
virtual bool Parse(const char *buf,int len,bool isFin);
|
||||
virtual bool Parse(io::InputStream *,bool isFin=true);
|
||||
};//class XMLParse
|
||||
|
||||
bool XMLParseFile(XMLParse *xml,const OSString &filename);
|
||||
|
||||
#define XML_START_PARSE(name) while(*name) \
|
||||
{ \
|
||||
const char *flag=*name;++name; \
|
||||
const char *info=*name;++name;
|
||||
|
||||
#define XML_END_PARSE() LOG_ERROR(UTF8String(__FILE__)+U8_TEXT(":")+UTF8String(__LINE__)+U8_TEXT(" can't parse atts \"")+UTF8String(flag)+U8_TEXT("\" , info \"")+UTF8String(info)+U8_TEXT("\".")); \
|
||||
}
|
||||
#define XML_END_PARSE_SKIP() ;}
|
||||
|
||||
#define xml_parse_skip(name) if(hgl::strcmp(flag,#name)==0)continue;else
|
||||
#define xml_parse_string_u16(name) if(hgl::strcmp(flag,#name)==0)name=to_u16(info);else
|
||||
#define xml_parse_string_u8(name) if(hgl::strcmp(flag,#name)==0)name=info;else
|
||||
#define xml_parse_int(name) if(hgl::strcmp(flag,#name)==0)hgl::stoi(info,name);else
|
||||
#define xml_parse_uint(name) if(hgl::strcmp(flag,#name)==0)hgl::stou(info,name);else
|
||||
#define xml_parse_float(name) if(hgl::strcmp(flag,#name)==0)hgl::stof(info,name);else
|
||||
#define xml_parse_bool(name) if(hgl::strcmp(flag,#name)==0)hgl::stob(info,name);else
|
||||
#define xml_parse_hexstr(name) if(hgl::strcmp(flag,#name)==0)hgl::ParseHexStr(name,info);else
|
||||
|
||||
#define xml_parse_to_string_u8(name,value) if(hgl::strcmp(flag,name)==0)value=info;else
|
||||
#define xml_parse_to_int(name,value) if(hgl::strcmp(flag,name)==0)hgl::stoi(info,value);else
|
||||
#define xml_parse_to_uint(name,value) if(hgl::strcmp(flag,name)==0)hgl::stou(info,value);else
|
||||
#define xml_parse_to_float(name,value) if(hgl::strcmp(flag,name)==0)hgl::stof(info,value);else
|
||||
#define xml_parse_to_bool(name,value) if(hgl::strcmp(flag,name)==0)hgl::stob(info,value);else
|
||||
|
||||
/** 使用范例:
|
||||
|
||||
<root>
|
||||
<role name="Bill" sex="true" age="18"/>
|
||||
<role name="Lucy" sex="false" age="17"/>
|
||||
</root>
|
||||
|
||||
void StartElement(const char *element_name,const char **atts) override
|
||||
{
|
||||
if(strcmp(element_name,"role")==0)
|
||||
{
|
||||
std::string name;
|
||||
bool sex;
|
||||
int age;
|
||||
|
||||
XML_START_PARSE(atts)
|
||||
|
||||
xml_parse_string_u8(name)
|
||||
xml_parse_bool(sex)
|
||||
xml_parse_int(age)
|
||||
|
||||
XML_END_PARSE
|
||||
}
|
||||
}
|
||||
*/
|
||||
}//namespace xml
|
||||
}//namespace hgl
|
||||
#endif//HGL_XML_PARSE_INCLUDE
|
||||
|
Reference in New Issue
Block a user