在学习SVG结构的时候,发现SVG结构可以通过以XML文件直接解析,所以就去了解了Tinyxml2库的使用,相关教程也比较多。
个人感觉Tinyxml2库比官方的XML解析库更好用,这里做个技术总结,记录Tinyxml2库解析XML文件结构的简单使用。
目录导读
- Tinyxml2库 介绍(文言一心)
- 使用CMAKE 和 MSVC 2017 编译 Tinyxml2库
- QT 调用 **tinyxml2.lib** 解析XML
- 遍历所有节点
- 将XML节点 加载到QTreeWidget 控件上
- 其他TinyXML2库操作XML示例:
Tinyxml2库 介绍(文言一心)
TinyXML-2 是一个简单、小巧且功能强大的C++ XML解析库,它是TinyXML的改进和扩展版本。该库专注于易用性和性能,提供了对XML文档的读取、修改和创建功能。以下是TinyXML-2的主要特点:
- DOM风格API: TinyXML-2采用了Document Object Model(DOM)风格的API,允许开发者以树形结构的方式操作XML数据。这意味着开发者可以轻松地遍历、查询和修改XML文档。
- 轻量级: TinyXML-2的代码量小,不依赖外部库,因此非常适合嵌入式系统和移动设备。由于其小巧的体积和高效的实现,它在处理XML文档的速度上表现出色。
- 易于使用: TinyXML-2的API设计直观、简洁,类和方法命名直观(如XMLNode、XMLElement等),使得学习成本较低,易于理解和集成到项目中。
- 错误处理: TinyXML-2提供了一套全面的错误检查机制。如果遇到无效的XML格式,它会抛出异常或返回错误代码,帮助开发者快速定位问题。
支持解析和生成:TinyXML-2支持从字符串或文件中解析XML文档,并且可以生成格式良好的XML文本。它能够处理各种节点类型,如元素、属性、文本、注释等。
- 跨平台: TinyXML-2完全基于标准C++编写,可以在多种操作系统和编译器环境下运行,包括Windows、Linux、Mac OS X等。
总的来说,TinyXML-2是一个功能强大、易于使用且跨平台的C++ XML解析库,适用于各种需要处理XML数据的场景。
Github: https://github.com/leethomason/tinyxml2
使用CMAKE 和 MSVC 2017 编译 Tinyxml2库
参考:xml开发笔记(一):tinyXml2库介绍、编译和工程模板
下载最新GitHub的项目通过CMAKE编译:
Configure选择MSCV2017编译器和X64平台:
直接Configure和Generate生成VS2017项目,可能是编译器或版本文件没有出现任何异常…
项目工程直接生成 tinyxml2.lib 没有了dll文件。
xmltest.cpp 文件为调用示例,建议参考。
QT 调用 tinyxml2.lib 解析XML
将项目中的 tinyxml2.h 和 tinyxml2.cpp ,tinyxml2.lib 放在项目目录下。
#include "tinyxml2/tinyxml2.h" using namespace tinyxml2; using namespace std; //! tinyxml2.lib 绝对路径 #pragma comment(lib,"E:\\data-bank\\Git\\Qt_XML_Lanalysis\\Qt_XML_Lanalysis\\XML_LAnalysis_UI\\tinyxml2\\tinyxml2.lib")
遍历所有节点
加载XML文件遍历所有节点,并输出节点中的所有属性值
参考:tinyxml/tinyxml2遍历所有节点
#include
#include #include #include #include #include #include void Lib_XmlReadWrite::GetEleValue(XMLElement * element) { for (XMLElement* currentele = element->FirstChildElement(); currentele; currentele = currentele->NextSiblingElement()) { XMLElement* tmpele = currentele; if (currentele->Name() != NULL||currentele->GetText() != NULL) qDebug() <<"-->" << currentele->Name() << ":" << currentele->GetText() ; if(tmpele->FirstAttribute()!=NULL) { //! 输出所有属性值 for (const XMLAttribute* var =tmpele->FirstAttribute(); var;var=var->Next()) { qDebug()<<"---->" < Name()<<" : "< Value(); } } //! 有子节点继续加载 if (!tmpele->NoChildren()) GetEleValue(tmpele); } } void Lib_XmlReadWrite::LoadXML(QString xml) { QFileInfo info("C:\\Users\\admin\\Desktop\\textxml\\text_xml5.xml"); qDebug()<< "LoadXML -->"< FirstChildElement()->Name(); qDebug()< Name(); qDebug()<<"-----------------------------------"; GetEleValue(doc.RootElement()); } 将XML节点 加载到QTreeWidget 控件上
通过 QTreeWidgetItem 结构将XML相关结构显示到 QTreeWidget 控件上。
值得注意的是 如果一个文件有多个根节点可以通过
for (XMLElement* root = doc.RootElement(); root; root = root->NextSiblingElement())
遍历所有根节点。
bool Lib_XmlReadWrite::LoadTreeWidget(QString xmlpath,QTreeWidgetItem* & item,QString& ErrorStr) { //! 判断文件是否存在! QFileInfo xmlInfo(xmlpath); if(!xmlInfo.exists()) { ErrorStr=("文件["+QString(xmlpath)+"]不存在!"); return false; } //! 加载xml格式文件 doc.Clear();; doc.LoadFile(xmlInfo.absoluteFilePath().toStdString().c_str()); if(doc.ErrorID()!=XML_SUCCESS) { ErrorStr=("解析失败:"+QString(doc.ErrorStr())); return false; } //! 添加文件根目录 item=new QTreeWidgetItem(QStringList()<
NextSiblingElement()) { //! XML子节点 QTreeWidgetItem* rootitem=new QTreeWidgetItem(QStringList()< Name())<<""< GetText(),QTreeWidgetItem::UserType); RecursionElement(root,rootitem); item->addChild(rootitem); } return true; } void Lib_XmlReadWrite::RecursionElement(XMLElement * element,QTreeWidgetItem* & item) { //! 查找当前 element 子节点 for (XMLElement* currentele = element->FirstChildElement(); currentele; currentele = currentele->NextSiblingElement()) { XMLElement* tmpele = currentele; QTreeWidgetItem* childitem=new QTreeWidgetItem(QStringList()< Name()<<""< GetText()); if(tmpele->FirstAttribute()!=NULL) { //! 添加属性值 for (const XMLAttribute* var =tmpele->FirstAttribute(); var;var=var->Next()) { QTreeWidgetItem* attritem=new QTreeWidgetItem(QStringList()<<""< Name()< Value(),QTreeWidgetItem::UserType); attritem->setToolTip(2,var->Value()); childitem->addChild(attritem); } } //! 查找 tmpele 子节点 if (!tmpele->NoChildren()) RecursionElement(tmpele,childitem); item->addChild(childitem); } } /*! //! 调用 void MainWindow::LoadXMLStructure(QString text) { ui->treeWidget->clear(); ui->treeWidget->setHeaderLabels(QStringList()<<"节点"<<"属性"<<"业务值"); ui->treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents); if(text=="") return; QString ErrorStr; QTreeWidgetItem* item; bool isbol=Lib_XmlReadWrite::LoadTreeWidget(text,item,ErrorStr); if(!isbol) { qDebug()<<"[ErrorStr] "< statusBar->showMessage(ErrorStr,0); } else { ui->treeWidget->addTopLevelItem(item); ui->treeWidget->expandAll(); } } */ 效果:
其他TinyXML2库操作XML示例:
TinyXML2库解析xml感觉比Qt的QXmlStreamReader这种更好用,
但是不适合用来解析HTML文件,HTML文件中,像这种节点会直接解析失败。
参考:
- TinyXML2使用方法及示例
- 官方示例 xmltest.cpp 文件
还没有评论,来说两句吧...