tinyxml2源码分析
时间:大一下刚开学
状态:看完c++ primer, 阅读完一遍Effective c++
Tinyxml2介绍:
主要思路:
- “找到一个入口”,从解析xml的类和函数入手
- “抓住主干”, 主要理解解析xml的算法设计和实现思路,和OO的设计思路
- ”有区别的对待不同的细节“,分清哪些细节对于理解代码有重要作用,哪些只是辅助实现
- “记录自己学到的新技术”,通过复述和总结提升自己
分析过程:
一:解析入口
tinyxml2有4k+lines的代码,在成功运行完样例之后。先查看文档,得知解析函数的入口。
int example_1()
{
XMLDocument doc;
doc.LoadFile( "resources/dream.xml" );
return doc.ErrorID();
}
tinyxml2提供XMLDocument类来作为外部接口,LoadFile负责从文件中读取字符串。紧接着调用Parse()
函数解析xml字符串。
char* p = _charBuffer;
p = XMLUtil::SkipWhiteSpace( p );
p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) );
// ...
ParseDeep(p, 0 );
从后面的分析可以看出,p指向正要解析的字符,SkipWhiteSpace( p )
用来跳过空白符。ReadBOM( p, &_writeBOM )
用来解析XML文档的BOM头(关于BOM头可以百度一下),这些函数都返回指向下一个未解析的字符的指针。
最后,调用ParseDeep(p, 0 );
开始标签的解析。
二:跟踪ParseDeep()
调用
由于XMLDocument并未重载此函数,所以调用的是XMLNode::ParseDeep()
。
while( p && *p ) {
//...
}
一个循环,大致可以猜到用来解析节点。接下来调用p = _document->Identify( p, &node );
,跟踪进去,有类似static const char* xmlHeader = { "<?" };
的常量,结合XML的知识,这些是开标签的一开始的几个符号。
XMLNode* returnNode = 0;
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );