TinyXML是一个简单小巧,可以很容易集成到其它E序中的C++ XML解析器?
它能做些什?/strong>
单地_TinyXML解析一个XML文档q由此生成一个可d修改可保存的文对象模型QDOMQ?
XML的意思是“可扩展标记语a“QeXtensible Markup
LanguageQ。它允许你创Z自己的文档标记。在为浏览器标记文斚wHTML做得很好Q然而XML允许你定义Q何文标讎ͼ比如可以Z个组l?
应用E序定义一个描q?#8220;to do”列表的文?
XML拥有一个结构化q且方便的格式,所有ؓ存储应用E序数据而创建的随机文g格式都可以用XML代替Q而这一切只需要一个解析器?
最全面正确的说明可以在http://www.w3.org/TR/2004/REC-xml-20040204/扑ֈQ但坦白地说Q它很晦涩难懂。事实上我喜?a >http://skew.org/xml/tutorial上关于XML的介l?
有不同的Ҏ可以讉K和与XML数据q行交互。TinyXML使用文对象模型QDOMQ,q意味着XML数据被解析成一个可被浏览和操作的C++
对象Q然后它可以被写到磁盘或者另一个输出流中。你也可以把C++对象构造成一个XML文然后把它写到盘或者另一个输出流中?
TinyXML被设计得Ҏ快速上手。它只有两个头文件和四个cpp文g。只需要把它们单地加到你的目中就行了。有一个例子文件——xmltest.cpp来引g该怎么做?
TinyXML以Zlib许可来发布,所以你可以在开源或者商业Y件中使用它。许可证更具体的描述在每个源代码文g的顶部可以找到?
TinyXML在保证正和恰当的XML输出的基上尝试成Z个灵zȝ解析器。TinyXML可以在Q何合理的C++适用pȝ上编译。它不依赖于
异常或者运行时cd信息Q有没有STL支持都可以编译。TinyXML完全支持UTF-8~码和前64k个字W实体(<i>译注Q如果你不明
白这句译文,可能你需要了解一下Unicode~码</i>Q?
它无法做些什?/strong>
TinyXML不解析不使用DTDsQ文档类型定义)或者XSLsQ可扩展样式表语aQ。有其它解析器(到www.sourceforge.org
搜烦一下XMLQ具有更加全面的Ҏ,但它们也更大,需要花更长的时间来建立你的目Q有更陡的学习曲U,而且l常有一个更严格的许可协议。如果你是用
于浏览器或者有更复杂的XML需要,那么TinyXML不适合你?
下面的DTD语法在TinyXML里是不做解析的:
<!DOCTYPE Archiv [
<!ELEMENT Comment (#PCDATA)>
]>
因ؓTinyXML把它看成是一个带着非法嵌入!ELEMENTl点?DOCTYPEl点。或许这在将来会得到支持?
指南
有耐性些Q这是一份能很好地指g怎么开始的指南Q它Q非常短精悍)值得你花旉完整地读上一遍?
代码状况
TinyXML是成熟且l过试的代码,非常健壮。如果你发现了漏z,h交漏z报告到sourcefore|站?Qwww.sourceforge.net/projects/tinyxmlQ?我们会尽快修正?
有些地方可以让你得到提高Q如果你对TinyXML的工作感兴趣的话可以上sourceforge查找一下?
相关目
你也怼觉得TinyXML很有用!Q简介由目提供Q?
Ҏ?/strong>
使用STL
TinyXML可以被编译成使用或不使用STL。如果用STLQTinyXML会用std::stringc,而且完全支持
std::istreamQstd::ostreamQoperator<<和operator>>。许多APIҎ都有
‘const char*’?#8217;const std::string&’两个版本?
如果被编译成不用STLQ则MSTL都不会被包含。所有stringc都由TinyXML它自己实现。所有APIҎ都只提供’const char*’传入参数?
使用q行时定义:
TIXML_USE_STL
来编译成不同的版本。这可以作ؓ参数传给~译器或者在“tinyxml.h”文g的第一行进行设|?
注意Q如果在Linux上编译测试代码,讄环境变量TINYXML_USE_STL=YES/NO可以控制STL的编译。而在Windows上,
目文g提供了STL和非STL两种目标文g。在你的目中,在tinyxml.h的第一行添?#define
TIXML_USE_STL"应该是最单的?
UTF-8
TinyXML支持UTF-8Q所以可以处理Q何语a的XML文gQ而且TinyXML也支?#8220;legacy模式”——一U在支持UTF-8之前使用的编码方式,可能最好的解释?#8220;扩展的ascii”?
正常情况下,TinyXML会检出正确的编码ƈ使用它,然而,通过讄头文件中的TIXML_DEFAULT_ENCODING|TinyXML可以被强制成L使用某一U编码?
除非以下情况发生Q否则TinyXML会默认用Legacy模式Q?
- 如果文g或者数据流以非标准但普遍的"UTF-8引导字节" (0xef 0xbb 0xbf)开始,TinyXML会以UTF-8的方式来d它?/li>
- 如果包含有encoding="UTF-8"的声明被dQ那么TinyXML会以UTF-8的方式来d它?/li>
- 如果d到没有指定编码方式的声明Q那么TinyXML会以UTF-8的方式来d它?/li>
- 如果包含有encoding=“其它~码”的声明被dQ那么TinyXML会以Legacy模式来读取它。在Legacy模式下,TinyXML会像以前那样工作Q虽然已l不是很清楚q种模式是如何工作的了,但旧的内容还得保持能够运行?/li>
- 除了上面提到的情况,TinyXML会默认运行在Legacy模式下?/li>
如果~码讄错误或者检到错误会发生什么事呢?TinyXML会尝试蟩q这些看g正确的编码,你可能会得到一些奇怪的l果或者ؕ码,你可以强制TinyXML使用正确的编码模式?
通过使用LoadFile( TIXML_ENCODING_LEGACY )或者LoadFile( filename,
TIXML_ENCODING_LEGACY )Q?
你可以强制TinyXML使用Legacy模式。你也可以通过讄TIXML_DEFAULT_ENCODING =
TIXML_ENCODING_LEGACY来强制一直用Legacy模式。同LQ你也可以通过相同的方法来强制讄?
TIXML_ENCODING_UTF8?
对于使用英文XML的英语用h_UTF-8跟low-ASCII是一L。你不需要知道UTF-8或者一点也不需要修改你的代码。你可以把UTF-8当作是ASCII的超集?
UTF-8q不是一U双字节格式Q但它是一U标准的Unicode~码QTinyXML当前不用或者直接支持wcharQTCHARQ或者微软的
_UNICODE?Unicode"q个术语被普遍地认ؓ指的是UTF-16Q一Uunicode的宽字节~码Q是不适当的,q是h的来源?
对于“high-ascii”语言来说——几乎所有非p语言Q只要XML被编码成UTF-8Q?
TinyXMLp够处理。说h可能有点微妙Q比较旧的程序和操作pȝ向于?#8220;默认”或?#8220;传统”的编码方式。许多应用程序(和几乎所有现在的应用
E序Q都能够输出UTF-8Q但是那些比较旧或者难处理的(或者干脆不能用的Q系l还是只能以默认~码来输出文本?
比如_日本的系l传l上使用SHIFT-JIS~码Q这U情况下TinyXML无法读取了。但是一个好的文本编辑器可以导入SHIFT-JIS的文本然后保存成UTF-8~码格式的?
Skew.org link上关于{换编码的话题做得很好?
试文g“utf8test.xml”包含了英文、西班牙文、俄文和体中文(希望它们都能够被正确地{化)?#8220;utf8test.gif”文g?
从IE上截取的XML文g快照。请注意如果你的pȝ上没有正的字体Q简体中文或者俄文)Q那么即使你正确地解析了也看不到与GIF文g上一L输出。同
时要注意在一个西方编码的控制CQ至我的Windows机器是这PQPrint()或者printf()也无法正地昄q个文gQ这不关
TinyXML的事——这只是操作pȝ的问题。TinyXML没有丢掉或者损坏数据,只是控制台无法显CUTF-8而已?
实体
TinyXML认得预定义的Ҏ“字符实体”Q即Q?
& &
< <
> >
" "
' ‘
q些在XML文d旉会被辨认出来Qƈ会被转化成等LUTF-8字符。比如下面的XML文本Q?
Far & Away
从TiXmlText 对象查询出来时会变成"Far & Away"q样的|而写回XML?文g时会?#8220;&”的方式写回。老版本的TinyXML“保留”了字W实体,而在新版本中它们会被转化成字W串?
另外Q所有字W都可以用它的Unicode~码数字来指定, " "? "都表CZ可分的空格字W?
打印
TinyXML有几U不同的方式来打印输出,当然它们各有各的优缺炏V?
- Print( FILE* )Q输出到一个标准C中Q包括所有的C文g和标准输出?/li>
- "相当漂亮的打?, 但你没法控制打印选项?/li>
- 输出数据直接写到FILE对象中,所以TinyXML代码没有内存负担?/li>
- 被Print()和SaveFile()调用?/li>
- operator<<Q输出到一个c++中?/li>
- 与C++ iostreams集成在一赗?/li>
- ?network printing"模式下输出没有换行符Q这对于|络传输和C++对象之间的XML交换有好处,但h很难阅读?/li>
- TiXmlPrinterQ输出到一个std::string或者内存缓冲区中?/li>
- APIq不是很l?/li>
- 来会增加打印选项?/li>
- 在将来的版本中可能有些细微的变化Q因为它会被改进和扩展?/li>
?/strong>
讄了TIXML_USE_STLQTinyXMLp支持C++(operator <<Q?gt;>Q和CQFILE*Q流。但它们之间有些差异你需要知道:
C风格输出Q?
- ZFILE*
- 用Print()和SaveFile()Ҏ
生成h很多I格的格式化q的输出Q这是ؓ了尽可能让h看得明白。它们非常快Q而且能够容忍XML文中的格式错误。例如一个XML文包含两个根元素和两个声明仍然能被打印出来?
C风格输入Q?/p>
- ZFILE*
- 用Parse()和LoadFile()Ҏ
速度快,定w性好。当你不需要C++时可以用它?
C++风格输出Q?
生成压羃q的输出Q目的是Z便于|络传输而不是ؓ了可L。它可能有些慢(可能不会Q,q主要跟你系l上ostreamcȝ实现有关。无法容忍格式错误的XMLQ此文只能包含一个根元素。另外根U别的元素无法以Ş式输出?
C++风格输入Q?
从流中读取XML使其可用于网l传输。通过些小技巧,它知道当XML文d完毕Ӟ后面的׃定是其它数据了。TinyXMLd定当它读取到
根结点后XML数据q束了。换句话_那些h不止一个根元素的文是无法被正读取的。另外还要注意由于STL的实现和TinyXML的限
Ӟoperator>>会比Parse慢一些?
I格
Ҏ保留q是压羃I格q一问题Zq没达成p。D个例子,假设‘_’代表一个空|对于"Hello____world"QHTML和某些XML
解析器会解释?Hello_world"Q它们压~掉了一些空根{而有些XML解析器却不会q样Q它们会保留I格Q于是就?
“Hello____world”Q记住_表示一个空|。其它的q徏议__Hello___world__应该变成Hello___world ?
q是一个解军_不能让我满意的问题。TinyXML一开始就两种方式都支持。调用TiXmlBase::SetCondenseWhiteSpace( bool )来设|你惌的结果,默认是压~掉多余的空根{?
如果惌改变默认行ؓQ你应该在解析Q何XML数据之前调用TiXmlBase::SetCondenseWhiteSpace( bool ) Q而且我不讄之后再去改动它?
句柄
惌健壮地读取一个XML文Q检查方法调用后的返回值是否ؓnull是很重要的。一U安全的错实现可能会产生像这L代码Q?
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.
用句柄的话就不会q么冗长了,使用TiXmlHandlec,前面的代码就会变成这P
TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
// do something useful
q处理v来容易多了?查阅TiXmlHandle可以得到更多的信息?
行列q踪
对于某些应用E序来说Q能够追t节点和属性在它们源文件中的原始位|是很重要的。另外,知道解析错误在源文g中的发生位置可以节省大量旉?
TinyXML能够q踪所有结点和属性在文本文g中的行列原始位置。TiXmlBase::Row() ?
TiXmlBase::Column()
Ҏq回l点在源文g中的原始位置。正的制表W号可以l由TiXmlDocument::SetTabSize() 来配|?
使用与安?/strong>
~译与运行xmltestQ?
提供了一个Linux Makefile和一个Windows Visual C++ .dsw 文g。只需要简单地~译和运行,它就会在你的盘上生成demotest.xml文gq在屏幕上输出。它q尝试用不同的方法遍历DOMq打印出l点数?
那个Linux makefile很通用Q可以运行在很多pȝ上——它目前已经在mingw和MacOSX上测试过。你不需要运?‘make depend’Q因为那些依赖关pdl硬~码在文仉了?
用于VC6的Windows目文g
- tinyxmlQ?tinyxml 库,非STL
- tinyxmlSTLQ?tinyxml 库,STL
- tinyXmlTestQ?用于试的应用程序,非STL
- tinyXmlTestSTLQ?用于试的应用程序,STL
Makefile
在makefile的顶部你可以讄Q?
PROFILEQDEBUGQ和TINYXML_USE_STL。makefile里有具体描述?
在tinyxml目录输入“make clean”然后“make”Q就可以生成可执行的“xmltest”文g?
在某一应用E序中用:
把tinyxml.cppQtinyxml.hQ?tinyxmlerror.cppQ?tinyxmlparser.cppQ?
tinystr.cppQ??tinystr.h
dC的项目和makefile中。就q么单,它可以在M合理的C++适用pȝ上编译。不需要ؓTinyXML打开异常或者运行时cd信息支持?
TinyXML怎么工作
举个例子可能是最好的办法Q理解一下:
<?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列表Q但它已l够了。像下面q样dq解析这个文Ӟ?#8220;demo.xml”Q你p创徏一个文档:
TiXmlDocument doc( "demo.xml" );
doc.LoadFile();
现在它准备好了,让我们看看其中的某些行和它们怎么与DOM联系h?
<?xml version="1.0" standalone=no>
W一行是一个声明,它会转化成TiXmlDeclaration c,同时也是文档l点的第一个子l点?
q是TinyXML唯一能够解析的指?Ҏ标签。一般来说指令标{会保存在TiXmlUnknown 以保证在它保存回盘时不会丢p些命令?
<!– Our to do list data –>
q是一个注释,会成Z个TiXmlComment对象?
<ToDo>
"ToDo"标签定义了一个TiXmlElement 对象。它没有M属性,但包含另外的两个元素?
<Item priority="1">
生成另一个TiXmlElement对象Q它?#8220;ToDo”元素的子l点。此元素有一个名?#8220;priority”和gؓ“1”的属性?
Go to the
TiXmlText Q这是一个叶子结点,它不能再包含其它l点Q是"Item" TiXmlElement的子l点?
<bold>
另一个TiXmlElement, q也?#8220;Item”元素的子l点?
{等
最后,看看整个对象树:
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"
文档
本文由Doxygen使用‘dox’配置文g生成?
许可?/strong>
TinyXMLZzlib许可证来发布Q?
本Y件按“现状”提供Q即现在你看到的样子Q,不做M明确或隐晦的保证。由使用此Y件所引v的Q何损失都决不可能׃者承担?
只要遵@下面的限Ӟ允怓Q何h把这软g用于M目的Q包括商业YӞ也允怿改它q自由地重新发布Q?
1. 决不能虚报Y件的来源Q你决不能声U是你是软g的第一作者。如果你在某个品中使用了这个YӞ那么在品文中加入一个致谢辞我们会很感激Q但qƈ非必要?
2. 修改了源版本应该清楚地标记出来Q决不能虚报说这是原始Y件?
3. 本通告不能从源发布版本中移除或做修攏V?
参考书?/strong>
万维|联盟是定制XML的权威标准机构,它的|页上有大量的信息?
权威指南Q?a >http://www.w3.org/TR/2004/REC-xml-20040204/
我还要推荐由OReilly出版由Robert Eckstein撰写?XML Pocket Reference"……q本书囊括了入门所需要的一切?
捐助者,联系人,q有?/strong>
非常感谢l我们徏议,漏洞报告Q意见和鼓励的所有h。它们很有用Qƈ且得这个项目变得有。特别感谢那些捐助者,是他们让q个|站面生机勃勃?
有很多h发来漏洞报告和意见,与其在这里一一列出来不如我们试着把它们写?#8220;changes.txt”文g中加以赞扬?
TinyXML的原作者是Lee Thomason(文中还l常出现“?#8221;q个? 。在Yves BerquinQAndrew EllertonQ和tinyXmlC的帮助下QLee查阅修改和发布新版本?
我们会很感激你的Q还有我们想知道你是否在使用TinyXML。希望你喜欢它ƈ觉得它很有用。请邮寄问题Q评论,漏洞报告l我们,或者你也可d|站与我们取得联p:
www.sourceforge.net/projects/tinyxml
Lee ThomasonQ?Yves BerquinQ?Andrew Ellerton

]]>