DuiLib 源码分析之解析xml类CMarkup & CMarkupNode 头文件
xml使用的还是比较多的,duilib界面也是通过xml配置实现的
duilib提供了CMarkkup和CMarkupNode类解析xml,使用起来也是比较方便的,比较好奇它是怎么实现的,如果自己来写一个
解析又需要怎样架构,架构之路还很遥远。。。
先来看看头文件吧,CMarkup主要是用于分割xml,判断xml格式是否正确;CMarkupNode主要是将CMarkup分割的xml,获取节点中的属性,
最多支持64个属性
enum
{
XMLFILE_ENCODING_UTF8 = ,//定义编码,默认使用utf8
XMLFILE_ENCODING_UNICODE = ,
XMLFILE_ENCODING_ASNI = ,
}; class CMarkup;
class CMarkupNode; class UILIB_API CMarkup//其实比较容易看懂
{
friend class CMarkupNode;
public:
CMarkup(LPCTSTR pstrXML = NULL);
~CMarkup(); bool Load(LPCTSTR pstrXML);
bool LoadFromMem(BYTE* pByte, DWORD dwSize, int encoding = XMLFILE_ENCODING_UTF8);//从内存中加载解析
bool LoadFromFile(LPCTSTR pstrFilename, int encoding = XMLFILE_ENCODING_UTF8);//从文件中加载解析
void Release();
bool IsValid() const; void SetPreserveWhitespace(bool bPreserve = true);
void GetLastErrorMessage(LPTSTR pstrMessage, SIZE_T cchMax) const;
void GetLastErrorLocation(LPTSTR pstrSource, SIZE_T cchMax) const; CMarkupNode GetRoot(); private:
typedef struct tagXMLELEMENT
{
ULONG iStart;//节点开始指针位置
ULONG iChild;//第一个孩子节点指针位置
ULONG iNext;//下一个兄弟节点指针位置
ULONG iParent;//父亲节点指针位置
ULONG iData;//节点属性结束的位置
} XMLELEMENT; LPTSTR m_pstrXML;//xml内存开始位置
XMLELEMENT* m_pElements;//数组储存节点信息
ULONG m_nElements;
ULONG m_nReservedElements;
TCHAR m_szErrorMsg[];
TCHAR m_szErrorXML[];
bool m_bPreserveWhitespace; private:
bool _Parse();
bool _Parse(LPTSTR& pstrText, ULONG iParent);//解析xml函数,主要是这里解析
XMLELEMENT* _ReserveElement();//如果数组不够长则扩充
inline void _SkipWhitespace(LPTSTR& pstr) const;
inline void _SkipWhitespace(LPCTSTR& pstr) const;
inline void _SkipIdentifier(LPTSTR& pstr) const;
inline void _SkipIdentifier(LPCTSTR& pstr) const;
bool _ParseData(LPTSTR& pstrText, LPTSTR& pstrData, char cEnd);//解析属性的值
void _ParseMetaChar(LPTSTR& pstrText, LPTSTR& pstrDest);//处理一些转义符号
bool _ParseAttributes(LPTSTR& pstrText);//解析属性
bool _Failed(LPCTSTR pstrError, LPCTSTR pstrLocation = NULL);
}; class UILIB_API CMarkupNode
{
friend class CMarkup;
private:
CMarkupNode();
CMarkupNode(CMarkup* pOwner, int iPos); public:
bool IsValid() const; CMarkupNode GetParent();
CMarkupNode GetSibling();
CMarkupNode GetChild();
CMarkupNode GetChild(LPCTSTR pstrName); bool HasSiblings() const;
bool HasChildren() const;
LPCTSTR GetName() const;
LPCTSTR GetValue() const;//这里获取不到节点的值,它返回的IData其实是属性末尾 bool HasAttributes();
bool HasAttribute(LPCTSTR pstrName);
int GetAttributeCount();
LPCTSTR GetAttributeName(int iIndex);
LPCTSTR GetAttributeValue(int iIndex);
LPCTSTR GetAttributeValue(LPCTSTR pstrName);
bool GetAttributeValue(int iIndex, LPTSTR pstrValue, SIZE_T cchMax);
bool GetAttributeValue(LPCTSTR pstrName, LPTSTR pstrValue, SIZE_T cchMax); private:
void _MapAttributes();//将之前分割好的xml映射到m_aAttributes中储存起来 enum { MAX_XML_ATTRIBUTES = }; typedef struct
{
ULONG iName;
ULONG iValue;
} XMLATTRIBUTE; int m_iPos;
int m_nAttributes;
XMLATTRIBUTE m_aAttributes[MAX_XML_ATTRIBUTES];
CMarkup* m_pOwner;//指向CMarkup指针,节点属性及值都是从这里获取
};
简单说一下这两个类的工作原理,首先用CMarkup加载xml入内存,在将其分割字符串,建立节点树的关系(通过XMLELEMENT*指向节点位置关系,iStart指向节点开始部分,iData指向节点末尾,iChild,iNext,iParent储存节点之间的关系),获取节点是属性则通过CMarkupNode根据节点iStart,iData的值进行属性提取。CMarkupNode用于获取属性值及获取父亲,兄弟,儿子节点,熟悉了这两个类的作用,使用起来就比较方便了,具体实现下次再详细说明。
DuiLib 源码分析之解析xml类CMarkup & CMarkupNode 头文件的更多相关文章
- DuiLib 源码分析之解析xml类CMarkup & CMarkupNode cpp文件
时隔5个月才有时间接着写未完成的实现部分,也是惭愧呀 选几个关机的函数来解析,一些get方法就忽略掉吧 CMarkupNode 与 CMarkUp 互为友元类,CMarkUp 实现解析,CMarkup ...
- Duilib源码分析(六)整体流程
在<Duilib源码分析(一)整体框架>.<Duilib源码分析(二)控件构造器—CDialogBuilder>以及<Duilib源码分析(三)XML解析器—CMarku ...
- Duilib源码分析(一)整体框架
Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析):通过XML布局界面,将用户界面和处理逻辑彻底 ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 百篇博客分析OpenHarmony源码 | v53.02
百篇博客系列篇.本篇为: v53.xx 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...
- v72.01 鸿蒙内核源码分析(Shell解析) | 应用窥伺内核的窗口 | 百篇博客分析OpenHarmony源码
子曰:"苟正其身矣,于从政乎何有?不能正其身,如正人何?" <论语>:子路篇 百篇博客系列篇.本篇为: v72.xx 鸿蒙内核源码分析(Shell解析篇) | 应用窥视 ...
- Duilib源码分析(三)XML解析器—CMarkup
上一节介绍了控件构造器CDialogBuilder,接下来将分析其XML解析器CMarkup: CMarkup:xml解析器,目前内置支持三种编码格式:UTF8.UNICODE.ASNI,默认为UTF ...
- Spring Developer Tools 源码分析:二、类路径监控
在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...
- MyBatis框架的使用及源码分析(四) 解析Mapper接口映射xml文件
在<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 一文中,我们知道mybat ...
随机推荐
- csuoj 1117: 网格中的三角形
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1117 1117: 网格中的三角形 Time Limit: 3 Sec Memory Limit: ...
- 使用Redux管理你的React应用(转载)
本文转载自: http://www.cnblogs.com/matthewsun/p/4773646.html
- C# MVC jsonp初接触成功
利用jsonp进行跨域请求资源 C# MVC ApiControllers准备如下: 1.需要在引用处右键管理NuGet安装jsonp插件 2.在Application_Start()中配置 Glob ...
- 怎样给Myeclipse配置tomcat服务器
http://jingyan.baidu.com/article/4853e1e53465271909f72690.html Meclipse是java Web企业级开发中最流行的工具,java we ...
- 计算ScrollView的当前页面
//每页宽度 CGFloat pageWidth = sender.frame.size.width; //根据当前的坐标与页宽计算当前页码 int currentPage = floor((send ...
- Array类
class Array Arrays are ordered, integer-indexed collections of any object. Array indexing starts at ...
- 【原创】如何用Android Studio断点安卓自带Service或Bind类型的Service
很久以来,我一直想找一种方法来断点调试安卓系统自身的Service,或者bind类型的Service,比如我想看WifiManager里面的getWifiApConfiguration函数是如何实现的 ...
- Caffe框架下的图像回归测试
Caffe框架下的图像回归测试 参考资料: 1. http://stackoverflow.com/questions/33766689/caffe-hdf5-pre-processing 2. ht ...
- html5与html4的区别,如何一眼区分
还是在面试过程中遇到的这个问题,但是当时感觉回答的不是很全面,回来以后自己做的总结: 以上这个问题如果教大家看源码,可能一眼很直观的就能认出,那个是html4,那个是html5,但是面试的时候问道这个 ...
- UVa 11235 RMQ
首先讲一下RMQ算法的意思. RMQ(Range Minimum Query,RMQ)范围最小值,给出一个n个元素的数组,计算min(A[L],A[L+1],...,A[R-1],A[R]): 这里运 ...