张弛
				<zhangchi@china.com>
		
		
				
						一、      
				
				TinyXml
				的特点
		
		
				TinyXml
				是一个基于
				DOM
				模型的、非验证的轻量级
				C++
				解释器。
		
		
				
						1.      
				
				SAX
				和
				DOM
		
		
				目前
				XML
				的解析主要有两大模型:
				SAX
				和
				DOM
				。
		
		
				其中
				SAX
				是基于事件的,其基本工作流程是分析
				XML
				文档,当发现了一个新的元素时,产生一个对应事件,并调用相应的用户处理函数。这种方式占用内存少,速度快,但用户程序相应得会比较复杂。
		
		
				而
				DOM
				(文档对象模型),则是在分析时,一次性的将整个
				XML
				文档进行分析,并在内存中形成对应的树结构,同时,向用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,速度往往慢于
				SAX
				,但可以给用户提供一个面向对象的访问接口,对用户更为友好。
		
		
				另据说,一些同时提供了
				SAX
				和
				DOM
				接口的库,是在底层先实现
				SAX
				,再在
				SAX
				的基础上实现
				DOM
				。
		
		
				目前我知道的
				XML
				解析库有下面几个:
		
		
				
						
								
										| 
														名称
												 | 
														访问接口
												 | 
														是否支持验证
												 | 
														备注
												 | 
								
										| 
														Expat
												 | 
														SAX/Local
												 | 
														不清楚
												 | 
														Local
														指它还有一套自己访问模型
												 | 
								
										| 
														LibXML2
												 | 
														SAX/DOM
												 | 
														是
												 | 
														
																  
												 | 
								
										| 
														TinyXml
												 | 
														DOM
												 | 
														否
												 | 
														
																  
												 | 
								
										| 
														XML4C
												 | 
														SAX/DOM
												 | 
														是
												 | 
														和
														Xerces-C
														是一家,不过用了
														ICU
														,国际化似乎更好
												 | 
								
										| 
														Xerces-C
												 | 
														SAX/DOM
												 | 
														是
												 | 
														
																  
												 | 
								
										| 
														XML Booster
												 | 
														Local
												 | 
														不清楚
												 | 
														这个库不是特别了解,好像是类似
														yacc
														那样,可以生成一个特定的解析器,估计效率应该很高(看名字也像)。
												 | 
						
				
		 
		
				
						 
				
		
		
		
		
				
						2.      
				
				验证和非验证
		
		
				对于一个特定的
				XML
				文档而言,其正确性分为两个层次。首先是其格式应该符合
				XML
				的基本格式要求,比如第一行要有声明,标签的嵌套层次必须前后一致等等,符合这些要求的文件,就是一个合格的
				XML
				文件,称作
				well-formatted
				。但除此之外,一个
				XML
				文档因其内容的不同还必须在语义上符合相应的标准,这些标准由相应的
				DTD
				文件或者
				Schema
				文件来定义,符合了这些定义要求的
				XML
				文件,称作
				valid
				。
		
		
				因此,解析器也分为两种,一种是验证的,即会跟据
				XML
				文件中的声明,用相应的
				DTD
				文件对
				XML
				文件进行校验,检查它是否满足
				DTD
				文件的要求。另一种是忽略
				DTD
				文件,只要基本格式正确,就可以进行解析。
		
		
				就我所知,验证的解析器通常都是比较重量级的。
				TinyXml
				不支持验证,但是体积很小,用在解析格式较为简单的
				XML
				文件,比如配置文件时,特别的合适。
		
		
				
						 
				
		
		
		
		
				
						二、      
				
				TinyXml
				的构建和使用
		
		
				
						1.      
				
				获取
		
		
				TinyXml
				首页在
				
						http://www.grinninglizard.com/tinyxml/index.html
				
				,从这里可以找到最新版本的源代码,目前的版本是
				
						2.3.4
				
				。
		
		
				
						2.      
				
				构建
		
		
				TinyXml
				在构建时可以选择是否支持
				STL
				,选择的话,则可以使用
				
						std::string
				
				,所以通常应该打开这个选项。
		
		
				在
				Windows
				上,
				TinyXml
				的源码包里提供了
				VC6
				的工程文件,直接用它就可以生成两个静态库(带
				STL
				和不带
				STL
				),非常容易。唯一需要注意的是,默认生成的库是单线程的,如果用在多线程的项目中,需要改动一下配置,生成相应的多线程库。
		
		
				在
				Unix
				平台上,
				TinyXml
				的源码包里只提供了一个
				
						Makefile
				
				,对于典型的
				Linux
				系统,或装了
				
						gcc
				
				和
				
						gmake
				
				的其他
				Unix
				,这个
				
						Makefile
				
				足够用了,我在
				RH9
				和
				RHEL4
				上测试,简单的
				make
				就成功了。需要注意的有以下几点:默认的编译是不支持
				STL
				的,可以通过编辑
				
						Makefile
				
				的
				TINYXML_USE_STL := NO
				那一行,把
				NO
				改成
				YES
				就可以支持
				STL
				了;还有默认只生成了一个测试程序,没有生成任何库,如果要生成静态库的话,可以用
				
						ar
				
				命令,将生成的几个目标文件打包就行了,如果要生成动态库,则需要加上
				-fpic
				参数重新编译。
		
		
				
						3.      
				
				使用
		
		
				构建了相应的库之后,在使用了它们的工程中,只要在连接时把他们连上就行了。需要注意的是,如果需要
				STL
				支持,在编译用到了
				TinyXml
				的文件时,需要定义一个宏
				TIXML_USE_STL
				,对
				
						gcc
				
				,可以使用参数
				-DTIXML_USE_STL
				,对
				cl.exe
				(
				VC
				),可以使用参数
				/DTIXML_USE_STL
				,如果嫌麻烦,可以直接定义在
				
						tinyxml.h
				
				文件里。
		
		
				
						 
				
		
		
		
		
				
						三、      
				
				TinyXml
				的编程模型
		
		
				
						1.      
				
				类之间的关系
		
		
				TinyXml
				实现的时
				DOM
				访问模型,因此提供了一系列的类对应
				XML
				文件中的各个节点。主要类间的关系如下图所示:
		
		
				
						
								
								
								
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
										
								
								
								
								
								
						
						
								
								
						
				
		
		
				
						TiXmlBase
				
				:其他类的基类,是个抽象类
		
		
				
						TiXmlNode
				
				:表示一个节点,包含节点的一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节电
		
		
				
						TiXmlDocument
				
				:表示整个
				XML
				文档,不对应其中某个特定的节点。
		
		
				
						TiXmlElement
				
				:表示元素节点,可以包含子节点和
				
						TiXmlAttribute
				
		
		
				
						TiXmlComment
				
				:表示注释
		
		
				
						TiXmlDeclaration
				
				:表示声明
		
		
				
						TiXmlText
				
				:表示文本节点
		
		
				
						TiXmlUnknown
				
				:表示未知节点,通常是出错了
		
		
				
						TiXmlAttribute
				
				:表示一个元素的属性
		
		
				下面是一个简单的例子:
		
		
				
						<?xml
				
				 version="1.0" encoding="utf-8" ?> 
		
		
		
		
				<!-This is only a sample--> 
		
		
		
		
				<book> 
		
		
		
		
				
						       <name>TinyXml How To</name> 
		
		
		
		
				
						       <price unit=”RMB”>20</price> 
		
		
		
		
				
						       <description>Some words…</description> 
		
		
		
		
				</ book > 
		
		
		
		
				整个文档,对应
				
						TiXmlDocument
				
		
		
				
						book,name,price
				
				, description
				,都对应
				
						TiXmlElement
				
		
		
				第一行对应一个
				
						TiXmlDeclaration
				
		
		
				第二行对应一个
				
						TiXmlComment
				
		
		
				“TinyXml How To”
				对应一个
				
						TiXmlText
				
		
		
				unit
				则是
				price
				的一个
				
						TiXmlAttribute
				
		
		
				这些类与
				XML
				文件中的相应元素都有很好的对应关系,因此相信参照
				TinyXml
				的文档,可以很容易的掌握各个方法的使用。
		
		
				
						 
				
		
		
		
		
				
						2.      
				
				需要注意的问题
		
		
				
						各类之间的转换
						
								
								
						
				
		
		
		
		
				由于各个节点类都从
				
						TiXmlNode
				
				继承,在使用时常常需要将
				
						TiXmlNode
				
				*
				类型的指针转换为其派生类的指针,在进行这种转换时,应该首先使用由
				
						TiXmlNode
				
				类提供的一系列转换函数,如
				
						ToElement
				
				(void)
				,而不是
				c++
				的
				
						dynamic_cast
				
		
		
				
						 
				
		
		
		
		
				
						检查返回值
						
								
								
						
				
		
		
		
		
				由于
				TinyXml
				是一个非校验的解析器,因此当解析一个文件时,很可能文件并不包含我们预期的某个节点,在这种情况下,
				TinyXml
				将返回空指针。因此,必须要对返回值进行检查,否则将很容易出现内存访问的错误。
		
		
				
						 
				
		
		
		
		
				
						如何重头建立一个
						XML
				
				
						文件
						
								
								
						
				
		
		
		
		
				先建立一个
				
						TiXmlDocument
				
				对象,然后,载入某个模板,或者直接插入一个节点作为根节点,接着就可以像打开一个已有的
				XML
				文件那样对它进行操作了。
		
		
				
						 
				
		
		
		
		
				
						四、      
				
				总结
		
		
				TinyXml
				最大的特点就是它很小,可以很方便的静态连接到程序里。对于像配置文件、简单的数据文件这类文件的解析,它很适合。但是由于它是非验证的,因此需要在程序里做许多检查工做,加重了程序编写的负担。因此对于复杂的
				XML
				文件,我觉得最好还是用验证的解析器来处理。