xml解析库对⽐总结(解析⽅式,第三⽅库,TinyXml)
⼀. 解析⽅式
xml的2种解析⽅式(DOM和SAX解析⽅式):
dom解析和sax解析区别:
dom⽅式解析
根据xml的层级结构在内存中分配⼀个树形结构,把xml的标签,属性和⽂本都封装成对象
优点:很⽅便实现增删改操作
缺点:如果⽂件过⼤,造成内存溢出
sax⽅式解析
采⽤事件驱动,边读边解析,从上到下,⼀⾏⼀⾏的解析,解析到某⼀个对象,返回对象名称,
当SAX解析结束,不会保存任何XML⽂档的数据。
优点:如果⽂件过⼤,不会造成内存溢出,⽅便实现查询操作
缺点:不能实现增删改操作
⼆. 第三⽅库介绍对⽐:
尽管XML解析器有很多种,⽽且功能差异很⼤,甚⾄是⽀持跨平台、多语⾔,但是对于你的应⽤⽽⾔,尽量选择⼀种相对熟悉、功能够⽤的即可,没必要去追求庞杂的解析器,我们只需关注:功能够⽤、相对稳定、适合扩展这三个功能即可。⼀旦有问题,修正和扩展都要更为容易。
PugiXML:
仅DOM⽅式;速度快;
RapidXML:
仅DOM⽅式;速度快
libxml:
可以验证;⼏乎适合于常见的所有操作系统下编译和开发使⽤; C代码⽀持XML解析最全的,⽀持xpat
h语法;
libxml++(地址:)是对libxml XML解析器的C++封装版本。此外还有各种语⾔封装包,参加官⽅链接。
libxml的使⽤(1)--读取xml:
libxml2的安装及使⽤[总结]:
Libxml2主要的优点有:
(  ):
1.  安装、使⽤⽐较简单,容易⼊门;
2.  ⽀持的编码格式较多,能很好的解决中⽂问题(使⽤⼀个很简单的编码转换函数);xml标签大全
3.  ⽀持Xpath解析(这点对于任意定位xml⽂档中的节点还是很有⽤的哦);
4.    ⽀持Well-formed 和valid验证,具体⽽⾔⽀持DTD验证,Schema验证功能正在完善中(⽬前多数解析器都还不完全⽀持shema验证功能);
5.  ⽀持⽬前通⽤的Dom、Sax⽅式解析等等。
不⾜之处也是有的:
1.  指针太多,使⽤不当时就会出现错误,在Linux系统中表现为常见的段错误,同样管理不当易造成内存泄漏;
2.个⼈认为内⾯有些函数的功能设计的不是很好(⽐如获取Xpath函数,它不获取节点属性,这样⼦有些情况会定位不准)
C/C++利⽤libxml2⾼效输出XML⼤⽂件详解:
Xerces:
⽀持SAX和DOM ;可以验证DTD;⽂件越⼤,element解析越慢;除了C++版本,Xerces同时还提供Xerces ,Xerces Perl等版本。TinyXML:
DOM⽅式;C++开发,⽀持Windows和Linux。⼩巧玲珑,⾮常适合存储简单数据,配置⽂件,对象序列化等数据量不是很⼤的操作。⽀持对XML的读取和修改,不直接⽀持XPath,需要借助另⼀个相关的类库TinyXPath才可以⽀持XPath.
⼀个例⼦:
TinyXml库 使⽤⽅法:
使⽤TinyXML读写xml⽂件:
TinyXml快速⼊门:
TinyXml⼊门简易教程:
-------------------------------------------------------------------------------------------------
配置使⽤过程:
1. tinyxml在windows环境下编译:
2. Windows下Tinyxml的正确配置:
(在 "项⽬" -> "xxx 属性" -> "配置属性" -> "连接器" -> "输⼊" 中, 到 "忽略特定默认库", 如果是 Debug 模式则向其中输⼊ libcmtd.lib 这步做与不做,有待进⼀步研究)
3. TinyXML Tutorial 中⽂指南:
在线⽂档: inninglizard/tinyxmldocs/tutorial0.html
------------------------------------------------------------------
遇到的问题:
tinyxml中⽂乱码(内存模式):
-------------------------------------------------------------------------------------------------
⼀个简单的实例应⽤:写xml⽂件
#include "tinyXml.h"
#pragma comment(lib, "tinyxml.lib")
#pragma comment(lib, "tinyxmlSTL.lib")
int main()
{
build_simple_doc();
system("pause");
return 0;
}
void build_simple_doc()
{
/*
<?xml version="1.0" encoding="utf-8" ?>
<scene version="0.5.0">
<integrator type="path">
<boolean name="hideEmitters" value="false" otherAttriube="someValue" />  </integrator>
<!--物体模型-->
</scene>
*/
TiXmlDocument doc;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
doc.LinkEndChild(decl);
TiXmlElement *rootElement = new TiXmlElement("scene");
rootElement->SetAttribute("version", "0.5.0");
//TiXmlText *text = new TiXmlText("world");
//rootElement->LinkEndChild(text);
doc.LinkEndChild(rootElement);
TiXmlElement *myIntegrator = new TiXmlElement("integrator");
myIntegrator->SetAttribute("type", "path");
rootElement->LinkEndChild(myIntegrator);
TiXmlElement *myBoolean = new TiXmlElement("boolean");
myBoolean->SetAttribute("name", "hideEmitters");
myBoolean->SetAttribute("value", "false");
myBoolean->SetAttribute("otherAttriube", "someValue");
myIntegrator->LinkEndChild(myBoolean);
/*
注意:myBoolean没有EndChild,所以不会有 </boolean> 这⼀⾏
同⼀个element不能添加两次(树结构),会导致卡死!!
*/
TiXmlComment *comment = new TiXmlComment();
comment->SetValue("物体模型");
rootElement->LinkEndChild(comment);
doc.SaveFile("l");
}
⼀个简单的实例应⽤:修改xml⽂件:
代码:
void modify_secene_xml(const char* pFilename)
{
printf("File: %-s:\n", pFilename);
TiXmlDocument doc(pFilename);
if (!doc.LoadFile()) return;
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
TiXmlHandle subRoot(0);
pElem = hDoc.FirstChildElement().Element();
if (!pElem) return;
hRoot = TiXmlHandle(pElem);
//pElem = hRoot.FirstChild("shape").FirstChildElement().Element();
//pElem = pElem->NextSiblingElement()->NextSiblingElement();
modify string in texture
pElem = hRoot.FirstChild("shape").FirstChild("bsdf").Element();
subRoot = TiXmlHandle(pElem);
pElem = subRoot.FirstChild("bsdf").FirstChild("texture").FirstChildElement().Element(); printf( "%-20s\t-->\t", pElem->Attribute("value") );
pElem->SetAttribute("value", "mydefine.png");    // <--------------------
printf("%-20s\n", pElem->Attribute("value"));
modify value of string of emitter
pElem = hRoot.FirstChild("emitter").FirstChild("string").Element();
printf("%-20s\t-->\t", pElem->Attribute("value"));
pElem->SetAttribute("value", "");  // <--------------------
printf("%-20s\n", pElem->Attribute("value"));
doc.SaveFile(pFilename);
}
//************************************************************//
int main()
{
modify_secene_xml("l");    // <--------------------
system("pause");
return 0;
}
待修改⽂件:(修改 "original.png" 及 "" )
<?xml version="1.0" encoding="utf-8" ?>
<scene version="0.5.0">
<integrator type="path">
<boolean name="hideEmitters" value="false" />
</integrator>
<!-- 物体模型 -->
<shape type="obj">
<string name="filename" value="template.obj" />
<transform name="toWorld">
<scale value="10" />
</transform>
<bsdf type="twosided">
<bsdf type="diffuse">
<texture type="bitmap" name="reflectance">
<string name="filename" value="original.png" />                </texture>
</bsdf>
</bsdf>
</shape>
<sensor type="perspective">
<float name="fov" value="60" />
<transform name="toWorld">
<lookat target="0 0 0" origin="-10 8 -10" up="0 1 0" />        </transform>
<sampler type="ldsampler">
<integer name="sampleCount" value="128" />
</sampler>
<film type="hdrfilm">
<boolean name="banner" value="false" />
<integer name="height" value="512" />
<integer name="width" value="512" />
<rfilter type="gaussian" />
</film>
</sensor>
<!-- 环境贴图 -->
<emitter type="envmap" id="Area_002-light">
<string name="filename" value="" />
<float name="scale" value="1" />
</emitter>
</scene>
打印结果:
三. 链接
C++各⼤有名库的介绍对⽐:
常见C/C++ XML解析器⽐较:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。