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 头文件的更多相关文章

  1. DuiLib 源码分析之解析xml类CMarkup & CMarkupNode cpp文件

    时隔5个月才有时间接着写未完成的实现部分,也是惭愧呀 选几个关机的函数来解析,一些get方法就忽略掉吧 CMarkupNode 与 CMarkUp 互为友元类,CMarkUp 实现解析,CMarkup ...

  2. Duilib源码分析(六)整体流程

    在<Duilib源码分析(一)整体框架>.<Duilib源码分析(二)控件构造器—CDialogBuilder>以及<Duilib源码分析(三)XML解析器—CMarku ...

  3. Duilib源码分析(一)整体框架

    Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析):通过XML布局界面,将用户界面和处理逻辑彻底 ...

  4. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

  5. 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 百篇博客分析OpenHarmony源码 | v53.02

    百篇博客系列篇.本篇为: v53.xx 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...

  6. v72.01 鸿蒙内核源码分析(Shell解析) | 应用窥伺内核的窗口 | 百篇博客分析OpenHarmony源码

    子曰:"苟正其身矣,于从政乎何有?不能正其身,如正人何?" <论语>:子路篇 百篇博客系列篇.本篇为: v72.xx 鸿蒙内核源码分析(Shell解析篇) | 应用窥视 ...

  7. Duilib源码分析(三)XML解析器—CMarkup

    上一节介绍了控件构造器CDialogBuilder,接下来将分析其XML解析器CMarkup: CMarkup:xml解析器,目前内置支持三种编码格式:UTF8.UNICODE.ASNI,默认为UTF ...

  8. Spring Developer Tools 源码分析:二、类路径监控

    在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...

  9. MyBatis框架的使用及源码分析(四) 解析Mapper接口映射xml文件

    在<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 一文中,我们知道mybat ...

随机推荐

  1. TCPL 札记

    1.函数原型符合设计要求,函数定义符合认知规律,做到见名知义,最少词汇量包含最大的信息量. 2.合理运用空行提高代码的可读性.从框架上来说有: 变量定义 初始化变量 处理 输出 返回值 3.采用伪码的 ...

  2. html radio check

    {% if classes|count > 1 %} <div class="class_checkbox" id="class_checkbox" ...

  3. [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. HTML5元素、属性和格式化

  5. JsonOperate 帮助类

    引用 Newtonsoft.Json using Newtonsoft.Json; using System; using System.Collections.Generic; using Syst ...

  6. 利用spring boot创建java app

    利用spring boot创建java app 背景 在使用spring框架开发的过程中,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置和复杂的bean依赖关系,特别是在使用mvc的时候各 ...

  7. 霍尼韦尔FC400A与FC400B的区别

    给霍尼韦尔官方打电话咨询了下,发现两者区别不大,唯一的区别是400B可以和主机联动,也就是主机关的时候,400B也可以自动关闭,不需要手动去关闭电源,这样非常方便. 本来官方是只有400A的时候,但是 ...

  8. 【笔记】js parentsNode,lastChild,appendChild,insertBefore,nextSibling的意义及运用

    这几天看书看到这几个属性做几个笔记 parentNode:顾名思义,就是获取某元素的父元素等同于jq的parent(). *注意一下,在调用parentNode 方法的时候 调用的对象必须是用ID 或 ...

  9. 总结/PSP初体验—排球计分程序1.0

    要做一个排球计分程序,墨迹了很长时间才做出个的东西,过程很不爽: 功能:这个软件有两个页面,可以实现窗体A的部分变化控制窗体B的部分变化.A是操作人员使用看到的,B是投放给观众的,完全由A操控: 学到 ...

  10. A ship is always safe at the shore - but that is not what it is built for.

    A ship is always safe at the shore - but that is not what it is built for. 船靠岸边总是安全的,但那不是建造它的目的.