TinyXML参考文档
TinyXML 2.6.2 参考文档
TinyXML是一个简洁的、可以很容易嵌入别的程序的C++ XML解析器。
能够做什么简单地说,TinyXML可以解析一个XML文档,并将此文档编辑成为一个文档对象模型(DOM),可以方便阅读、编辑与保存。
XML(扩展标记语言,eXtensible Markup Language)准许你定义属于自己的文档标记。HTML为浏览器的做了非常多得工作。XML准许你定义任何类型的文档标记,例如一个描述管理应用的”to do”列表。XML是一个结构化的、便捷的格式。所有为了存储应用程序数据的非常随意的文件格式都可以被XML取代。可以这么说TinyXML可以解析所有的文档。
最全面、最正确和最权威的参考网站: http://www.w3.org/TR/2004/REC-xml-20040204/。对XML的介绍(我非常喜欢)的网站:http://skew.org/xml/tutorial.
有很多方法去访问以及与XML交互数据。TinyXML使用文档对象模型(DOM),即XML数据被解析成C++对象,这样很容易浏览、操作或者被写入磁盘以及其他数据流。你当然也可以将XML的草稿文档写入C++对象以及保存到磁盘以及其他的数据流。
由于TinyXML在ZLib协议下发布的,你可以在开发源代码以及商业代码中使用它。关于这个协议的详细信息,可以参考任何源码文件的最前部。
TinyXML的目的是成为一个灵活的解析器,并且可以输出正确合理的XML文档。TinyXML可以在任何合理的C++编译系统上编译。它并不依赖异常与RTTI。它可以被编译成支持或者不支持STL的不同版本。TinyXML完美支持UTF-8编码和64k字符集。
不能做什么TinyXML不能解析或者使用DTDs(DocumentType Definitions)或者XSLs(eXtensible StylesheetLanguage)。有别的解析器去解析它们(可以在www.sourceforge.org中搜索”XML”)。但是它们要大的多,并且需要长时间的项目设置、长时间的学习以及更多严格的协议约束。TinyXML并不适合于从事浏览器开发或者其他对XML要求更全面的人。
下面的DTD语句并不能在当前的TinyXML中被解析:
<!DOCTYPE Archiv [
<!ELEMENT Comment (#PCDATA)>
]>
TinyXML会将此看会!DOCTYPE节点,但是嵌入了一个错误的!ELEMENT节点。这些将在下面提及。
教程对于没有耐心的人,下面的教程可以帮助你。一个非常适合于入门,并且非常值得你通篇阅读的参考文档。
TinyXML教程
代码现状TinyXML是一个成熟的,经过测试的代码。它非常稳定。如果你发现任何bug,请在sourceforge网站上(www.sourceforge.net/projects/TinyXML)写一个bug报告,以方面我们立即获知它们。
相关项目
TinyXML项目或许对你非常有用!
TinyXPath(http://tinyxpath.sourceforge.net).一个用C++编写的小型的XPath语法解码器
TinyXML++(http://code.google.com/p/ticpp/)。TinyXML++对于TinyXML来说是一个全新的接口,它使用了很多C++知识:模版、异常处理和更健全的错误处理机制。
特点使用STLTinyXML可以被编译成支持或者不支持STL的不同版本。一旦使用STL,TinyXML可以使用std::string类,完美支持std::istream, std::ostream,operator<<和operator>>。很多API方法有”const char*”与”conststd::string&”两中格式。
当被编译成非STL版本时,没有STL文件被引用.所有的string类都被替换为TinyXML定义的类.所有的API方发都是用”constchar*”类型。
使用如下的编译时宏定义去控制编译哪个版本。
TIXML_USE_STL
可以通过传递此宏给编译器或者在”TinyXML.h“文件的第一行定义该宏的方法。
注意:如果你在Linux下编译测试代码,设置环境变量TINYXML_USE_STL=YES/NO可以控制是否支持STL。在Windows的项目文件中,STL与非STL的目标配置都已经提供了。
UTF-8TinyXML支持UTF-8,这就准许处理任何语言的XML文件。TinyXML也支持所谓的”遗传模式”----一种在UTF-8模式被支持之前的编码方式,或者可以被描述为”扩展ASCII“。
TinyXML在正常情况下会尝试检测并且使用正确的编码方式。然而,通过设置在头文件中TIXML_DEFAULT_ENCODING的值,TinyXML可以被强制指定使用一种编码方式。
TinyXML将假定使用“遗传模式”,直到下面的情况发生:
1. 如果文件或者数据流以非标准但是却通用的UTF-8开始字符(0xef 0xbb 0xbf)开头,TinyXML将使用UTF-8模式。
2. 如果声明标记被读到,并且指定为UTF-8,TinyXML将使用UTF-8模式。
3. 如果声明标记被读到,并且没有指定任何模式,TinyXML将使用UTF-8模式。
4. 如果声明标记被读到,并且被指定为未识别的模式(somethingelse),TinyXML将使用遗传模式。在遗传模式下,TinyXML会按照以前的模式工作。它并不清楚是哪种具体的模式,但是久的内容将会正常工作。
5. 直到上面的任何一种规则被遇到,否则TinyXML会按照遗传模式工作。
当编码方式没有被正确地设置或者检测到会发生什么呢?TinyXML将尝试去读并且忽略非正常编码的文本。你或许会得到奇怪的结果或者损坏的字符。你或者想强制TinyXML使用正确的模式。
你可以通过LoadFile(TIXML_ENCODING_LEGACY)或者LoadFile(filename, TIXML_ENCODING_LEGACY)接口强制TinyXML使用遗传模式。你也可以通过设置TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY强制TinyXML在任何时候都使用遗传模式。当然,你也可以通过同样的方法设置强制TinyXML使用TIXML_ENCODING_UTF8模式。
针对英语用户,使用英文版的TinyXML,UTF-8与low-ASCII类似。你并不需要关注UTF-8或者改变你的编码方式。你仅仅需要把UTF-8为ASCII的超集。
UTF-8并不是双字符模式-但是它是Unicode的标准编码模式!TinyXML在当前并不使用或者直接支持wchar,TCHAR或者微软的_UNICODE。这些编码方式有点复杂,老代码和老操作系统趋向于使用”默认的“或者”传统的“代码页。许多应用(并且几乎所有的现代版本)都可以输出UTF-8,但是旧的或者顽固的(或者仅仅被打断的)应用还用默认的方式输出代码页。
例如,日文版的系统传统上使用SHIFT-JIS编码方式。按照SHIFT-JIS模式编码的文本并不会被TinyXML正确读取。一个优秀的文本编辑器支持将SHIFT-JIS编码的文本导入,然后另存为UTF-8模式。
Skew.org为编码问题做了大量的工作。
测试文件”utf8test.xml”是一个包含英文、西班牙文、俄文和简体中文的XML文档。(真希望它们能够正确翻译)“utf8test.gif“是该文件的截图,可以在IE上显示。值得注意的是:如果你的系统没有正确的字符(简体中文或者俄文),你将不会看到如GIF图片上的显示即使解析正确。更要注意(至少在我的Windows机器上)控制台以西文编码方式显示,所以Print()或者printf()并不能正常显示该文件。这并不是TinyXML的bug-仅仅是操作系统的问题。并没有数据被TinyXML丢失或者破坏。控制台并不能显示UTF-8编码方式。
实体(Entities)TinyXML识别预定义的“字符实体”为特殊字符,即:
& &
< <
> >
" "
' '
当XML文档被读取的时候它们被识别,并且被翻译成等效的UTF-8模式。例如,XML文本:
Far& Away
查询TiXmlText对象的Value()方法时,将拥有”Far & Away“,并且以&将被写回XML流/文件。旧版本的TinyXML会保留这些字符实体,但是新版本会将它们翻译成字符。
另外,任何字符都可以通过Unicode编码的标点指定。如语法”
”或者“ ”都会被翻译为非破裂的空字符。
打印(Printing)TinyXML可以以多种方式打印结果,有长处也有限制。
Print(FILE*):输出为标准C数据流,包括所有的C文件和stdout。
> “完美打印“,你并不能控制打印选项
> 结果直接以流的方式输出到FILE对象,TinyXML并没有内存开销。
> 使用Print()与SaveFile()方法
operator<<:输出为C++流
> 与标准C++流集成
> 网络打印模式打印的结果中没有换行符。方便网络传输和在C++对象间传递XML,并不适合人类阅读。
TiXmlPrinter:输出为std::string或内存缓冲区
> API不简明
> 将来的打印控制可以放在这里
> 打印方法将来只需少量的改变就得以改善与扩展
流(Streams)通过设置TIXML_USE_STL,TinyXML可以像支持C流(FILE*)一样支持C++流(operator<<, >>)。有写不同点值得你关注。
C格式输出:基于FILE*
通过Print()与SaveFile()方法
为了尽可能具有可读性,它产生具有大量空白字符的格式化输出结果。这种方式非常快,并且具有XML文档的容错性。例如,一个具有2个根节点与2个声明的XML文档同样也可以直接打印。
C格式输入:基于FILE*
通过Parse()与LoadFile()方法
一个快速并且具有容错性的读操作。在不需要C++流的时候使用。
C++格式输出:基于std::stream
operator<<
为了方便网络传输而不是可读性,产生压缩性的输出结果。依靠你的系统对于ostream类的实现,这种方法或许有些慢(或者并不慢)。不具有XML的容错性:文档必须包含一个根节点。另外,根节点级别的其余元素都不会被输出。
C++格式输入:基于std::istream
operator>>
从数据流读入XML,使它方便网络传输。复杂的地方是:当没有别的数据在流中时,就认为XML文档结束。然而,TinyXML假定在读完根节点元素时就认定XML数据结束。即,如果文档错误地构造为包含不止一个根节点时就不能正确地被读取。注意:由于STL的实现方法与TinyXML的限制,operator>>在很大程度上比Parse接口慢。
空白字符(White Space)这个世界针对空白字符是否需要保留与压缩并没有达成一致。例如,假设‘_’是一个空格,现在来看”Hello____world”。HTML与至少一些XML解析器,将它解析为“Hello_world”。他们压缩了空白字符。一些XML解析器并不压缩,而将之保留为“Hello____wrld”。(注意假设_为空格)另外一些解析器建议将__Hello____world__解析为Hello____world。
这些并不能使我满足。TinyXML支持头2中方法。调用TiXmlBase::SetCondenseWhiteSpace(bool)来设置期望的方式。默认设置为压缩空白字符。
如果你想改变默认方式,你需要在调用任何解析XML数据之前调用TiXmlBase::SetCondenseWhiteSpace(bool)。我并不推荐在之后调用该方法。
句柄(Handles)当随意浏览XML文档时,检测调用方法的返回结果是否为null是很有必要的。一个容错的安全实现需要产生大量的代码,如下:
TiXmlElement* root = document.FirstChildElement( "Document" );
if ( root )
{
TiXmlElement* element = root->FirstChildElement( "Element" );
if ( element )
{
TiXmlElement* child = element->FirstChildElement( "Child" );
if ( child )
{
TiXmlElement* child2 = child->NextSiblingElement( "Child" );
if ( child2 )
{
// Finally do something useful
句柄可以将这些代码清除掉。使用TiXmlHandle类,上面的代码可以削减为:
TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
// do something useful
这更容易处理。查看TiXmlHandle类了解更多。
行与列跟踪(Row and Column Tracking)能够知道节点与属性在源文件中的原始位置对于应用程序来说是非常必要的。另外,知道在源文件的何处解析错误非常节省时间。
TinyXML能够跟踪文本文件中任何节点或属性的行与列的位置。TiXmlBase::Row()与TiXmlBase::Column()方法将返回节点在源文件中的原始位置。正确制表符可以通过TiXmlDocument::SetTabSize()去设定。
使用与安装(Using and Installing)编译与运行xmltest:源码中提供了Linux的Makefile文件与Windows的C++ .dsw文件。简单地编译并且运行。将会在你的磁盘上写产生demotest.xml文件并且在屏幕上显示结果。它能够以多种方式打遍历DOM(文档对象模型)并打印节点数。
Linux makefile文件是非常通用的并且可以在多种系统上执行 – 当前只在mingw和MacOSX上测试。你并不需要执行’make depend‘。依赖关系是被写死的(hard coded)。
Windows下的VC6项目文件TinyXML:TinyXML库,非STL版本
TinyXMLSTL:TinyXML库,STL版本
TinyXMLTest:测试程序,非STL版本
TinyXMLTestSTL:测试程序,STL版本
Makefile在该文件的头部你可以设置:
PROFILE,DEBUG与TINYXML_USE_STL。更详细的内容(像你们看到的一样)在makefile中。
在TinyXML目录中,先执行“make clean”,然后执行“make”。这样就会产生名为“xmltest”的可执行文件。
在应用程序中使用(To User in an Application)在你的项目文件或者make文件中添加TinyXML.cpp,TinyXML.h,TinyXMLerror.cpp,TinyXMLparser.cpp,tinystr.cpp与tinystr.h!这就是全部。这就可以在任何合理的C++编译系统上编译。你并不需要为TinyXML打开异常与RTTI。
TinyXML是如何工作的(How TinyXML works)一个例子或许是最好的开始方法。例如:
<?xml version="1.0" standalone=no>
<!-- Our to do list data -->
<ToDo>
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
<Item priority="2"> Do bills</Item>
</ToDo>
它并没有过多的To Do列表,但是完全可以说明问题。为了读取这个文件(demo.xml),你需要创建一个文档并且解析它:
TiXmlDocument doc( "demo.xml" );
doc.LoadFile();
它开始工作了。现在让我们来看看一些行,并且看看他们是如何关联DOM的。
<?xml version="1.0" standalone=no>
文档的第一行,将被转换成TiXmlDeclaration类。它将会是文档节点的第一个孩子。
这是仅有的被TinyXML解析的指令/特殊标记。通常指令标记被保存在TiXmlUnknown类中,所以这些指令不会被漏写入磁盘。
<!-- Our to do list data -->
注释。会被解析成TiXmlComment对象。
<ToDo>
“ToDo”标记定义了TiXmlElement对象。这个节点没有包含任何属性,但是包含了2个其它元素。
<Item priority="1">
创建了另一个TiXmlElement对象,它是“ToDo”元素的孩子。这个元素有1个名为“priority”,值为“1”的属性。
Go to the
一个TiXmlText。这是一个叶节点,不可以拥有其它提点。它是“Item”TiXmlElement“的孩子。
<bold>
另一个TiXmlElement,它是”Item“元素的一个孩子。
等等……
现在看看整个对象树,结束以:
TiXmlDocument "demo.xml"
TiXmlDeclaration "version='1.0'" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills"文档(Documentation)
帮助文档是通过Doxygen创建的,使用”doc“配置文件。
许可(License)TinyXML在zlib许可协议下发行:
该软件按照’as-is‘方式提供,不会有任何明确或隐含的授权。作者并不对使用该软件承担任何损害性的责任。
在以下的约束下,准许任何人以任何目的使用该软件,包括:商业应用,自由地修改并且发行:
1. 软件的原创不能够予以错误的报道:你不能够声明你参与了原始软件的开发工作。如果你在产品中使用该软件,在产品文档的致谢写入是值得欣赏的,但并不是必须的。
2. 修改原始版本必须清楚声明,并且不能够被误解为是原始的软件。
3. 这个通知不可以从任何源码版本中删除或修改。
参考(References)万维网组织定义了XML的标准部分,并且他们的网页上包含了大量的参考信息。
参考页面: http://www.w3.org/TR/2004/REC-xml-20040204/
(注:翻译的不当之处,请指出)