zl程序教程

您现在的位置是:首页 >  工具

当前栏目

第二人生的源码分析(六十九)使用LLXmlTree类来分析XML配置文件

源码XML配置文件 分析 第二 人生 使用
2023-09-14 09:10:42 时间
前面已经介绍使用 expat库来分析XML数据,那么在第二人生里是怎么样分析XML配置文件的呢?现在就来分析这方面的问题,先来看看第二人生分析配置文件调用关系,如下:
1.       LLAppViewerWin32::init()
2.       LLAppViewer::init()
3.       LLControlGroup::loadFromFile()
4.       LLXmlTree::parseFile()
5.       LLXmlTreeParser::parseFile()
6.       LLXmlParser::parseFile()
 
从这个调用关系,可以看到分析配置文件是调用类 LLControlGroup、类LLXmlTree、类LLXmlTreeParser和类LLXmlParser共同完成这项任务的。类LLControlGroup是控件的状态保存,类LLXmlTree是把XML数据按树表示,类LLXmlTreeParser是保存树形节点的分析类,类LLXmlParser与上面介绍使用expat类一样的,都是封装expat库函数。因此,现在先来看类LLXmlParser类的声明,如下:
#001 class LLXmlParser
#002 {
#003 public:
 
构造函数和析构函数。
#004     LLXmlParser();
#005     virtual ~LLXmlParser();
#006 
 
这个函数分析给出文件名称的 XML文件。
#007     // Parses entire file
#008     BOOL parseFile(const std::string &path);
#009 
 
分析给出缓冲区的 XML数据。
#010     // Parses some input. Returns 0 if a fatal error is detected.
#011     // The last call must have isFinal true;
#012     // len may be zero for this call (or any other).
#013     S32 parse( const char* buf, int len, int isFinal );
#014 
 
获取出错的字符串。
#015     const char* getErrorString();
#016    
 
获取当前行号。
#017     S32 getCurrentLineNumber();
#018 
 
获取当前行的列号。
#019     S32 getCurrentColumnNumber();
#020 
 
获取 XML元素节点的深度。
#021     S32 getDepth() { return mDepth; }
#022 
#023 protected:
 
处理元素开始和结束的函数。
#024     // atts is array of name/value pairs, terminated by 0;
#025     // names and values are 0 terminated.
#026     virtual void startElement(const char *name, const char **atts) {}
#027 
#028     virtual void endElement(const char *name) {}
#029 
#030     // s is not 0 terminated.
#031     virtual void characterData(const char *s, int len) {}
#032    
#033     // target and data are 0 terminated
#034     virtual void processingInstruction(const char *target, const char *data) {}
#035 
#036     // data is 0 terminated
#037     virtual void comment(const char *data) {}
#038 
#039     virtual void startCdataSection() {}
#040 
#041     virtual void endCdataSection() {}
#042 
#043     // This is called for any characters in the XML document for
#044     // which there is no applicable handler. This includes both
#045     // characters that are part of markup which is of a kind that is
#046     // not reported (comments, markup declarations), or characters
#047     // that are part of a construct which could be reported but
#048     // for which no handler has been supplied. The characters are passed
#049     // exactly as they were in the XML document except that
#050     // they will be encoded in UTF-8. Line boundaries are not normalized.
#051     // Note that a byte order mark character is not passed to the default handler.
#052     // There are no guarantees about how characters are divided between calls
#053     // to the default handler: for example, a comment might be split between
#054     // multiple calls.
#055     virtual void defaultData(const char *s, int len) {}
#056 
#057     // This is called for a declaration of an unparsed (NDATA)
#058     // entity. The base argument is whatever was set by XML_SetBase.
#059     // The entityName, systemId and notationName arguments will never be null.
#060     // The other arguments may be.
#061     virtual void unparsedEntityDecl(
#062         const char *entityName,
#063         const char *base,
#064         const char *systemId,
#065         const char *publicId,
#066         const char *notationName) {}
#067 
#068 public:
#069     ///
#070     // Pseudo-private methods. These are only used by internal callbacks.
#071    
 
下面这些函数是静态函数,在里面都是调用本类的虚函数来处理的。
#072     static void startElementHandler(void *userData, const XML_Char *name, const XML_Char **atts);
#073     static void endElementHandler(void *userData, const XML_Char *name);
#074     static void characterDataHandler(void *userData, const XML_Char *s, int len);
#075     static void processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data);
#076     static void commentHandler(void *userData, const XML_Char *data);
#077     static void startCdataSectionHandler(void *userData);
#078     static void endCdataSectionHandler(void *userData);
#079     static void defaultDataHandler( void *userData, const XML_Char *s, int len);
#080     static void unparsedEntityDeclHandler(
#081         void *userData,
#082         const XML_Char *entityName,
#083         const XML_Char *base,
#084         const XML_Char *systemId,
#085         const XML_Char *publicId,
#086         const XML_Char *notationName);
#087 
#088 
#089 protected:
#090     XML_Parser      mParser;
#091     int             mDepth;
#092     char            mAuxErrorString[1024];      /*Flawfinder: ignore*/
#093 };
#094 
 
通过上面的类在构造函数里创建 expat库,并且在函数LLXmlParser::parseFile读取XML文件的数据,提供给expat分析,这样就会生成XML树表的数据。下一次再来分析类LLXmlTreeParser。