介绍
我们知道osgearth是通过.earth文件来实现数据的持久化,而OE实现earth 文件序列化最重要的类就config,
Config 主要是文档的存储方式的体现,通过数据集合来调整文档中元素的关系;设计过程中涉及到模板和泛型编程;支持XML和Json 文档格式
Config内主要实现的是集合操作,本身包含着一个本身类型的集合 ConfigSet _children;
通过泛型编程让Config能兼容各种数据操作,同时重复着各种集合操作来完成各种类型的数据操作。
结构图
如何序列化?
例子:
<image name="readymap_imagery" driver="gdal">
<url>../data/world.tif</url>
<color_filters>
<gamma rgb="1.3"/>
</color_filters>
</image>
打开osgEarth类库,找到XMLUtils类
通过代码,可以发现OE用如下节点表示XML节点
XmlText: 对应XML文档中的TiXmlText
节点,XmlText用属性value表示
如上面例子的:.<<./data/world.tif>>
XmlElement: 对应于XML文档中的TiXmlElement
节点,XmlElement用属性map集合 attrs存储,用name保存 TiXmlElement的名字
用于XmlNodeList 节点保存所有子节点
所以 OE在一开始程序遍历XML文档,遇到TiXmlElement节点就作为XmlElement(录入相关属性值如果有)传入XmlNodeList(children)中,遇到TiXmlText就作为XmlText节点录入XmlNodeList中.
具体读取过程
首先打开XmlUtils文档,位于osgearth类库中
要理解,XmlUtils把XML内的节点之分两类,不是元素节点就是文本节点
XMLDocument将告诉我们一切,首先它有三个重载函数load()告诉我们将XML文件析取到内存中,跟随代码我们来到了 processNode( doc, xmlDoc.RootElement() ),该方法中我们知道了,XMLEment析取XML包含重要的一步是判断当前节点上是元素节点,还是文本节点,如果是元素节点需要新建XmlElment节点保存它所有节点,并按深度递归其子节点,如果是文本节点则作为子节点保存在当前的XmlElment父节点中,直到最底层的XmlElement元素,然后递归最底层的兄弟节点,递归最底第二层的节点...这样,Xml文档就用XmlElement类将他们串起来了
理清了XmlElement中的保存规则,就不难理解XmlElement到Config的过程了。
代码位于 XmlElement::getConfig() 创建Config,将XmlElement中的元素集合项作为Config子节点并入Config(无子项),递归遍历XmlElement的子元素并入Config(可能Config中还有Config),读入对应XmlElement中的文本节点,返回父节点,继续递归......