如何在Qt/C++中正确读取XML文件的全部目标元素
问题:遍历SVG XML所有目标元素
目标SVG文件内容
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#"> <metadata id="metadata1030"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title /> </cc:Work> </rdf:RDF> </metadata> </svg>
原读取代码
#include <QCoreApplication> #include <QtSvg> #include <iostream> #include <QTextStream> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFile file("example.svg"); file.open(QIODevice::ReadOnly | QIODevice::Text); QXmlStreamReader reader(&file); while(!reader.atEnd()) { auto token = reader.readNextStartElement(); qDebug()<<reader.name(); } return a.exec(); }
当前输出结果
"svg" "metadata" "RDF"
期望输出结果
"svg" "metadata" "RDF" "Work" "format" "type"
解决方案
原代码使用readNextStartElement()仅会读取当前层级的起始元素,无法深入遍历子元素层级。通过递归遍历的方式可以处理所有层级的元素:
#include <QCoreApplication> #include <QtSvg> #include <QDebug> // 递归遍历并输出所有起始元素名称 void traverseElements(QXmlStreamReader &reader) { while (!reader.atEnd()) { QXmlStreamReader::TokenType token = reader.readNext(); if (token == QXmlStreamReader::StartElement) { qDebug() << reader.name(); // 递归处理当前元素的子元素 traverseElements(reader); } else if (token == QXmlStreamReader::EndElement) { // 遇到结束元素,返回上层继续遍历 reader.readNext(); break; } // 忽略其他类型的token(如注释、文本等) } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFile file("example.svg"); // 增加文件打开失败的判断 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "无法打开文件:" << file.errorString(); return 1; } QXmlStreamReader reader(&file); traverseElements(reader); // 检查XML是否解析错误 if (reader.hasError()) { qDebug() << "XML解析错误:" << reader.errorString(); } file.close(); return a.exec(); }
修改说明
- 新增递归函数
traverseElements,负责遍历当前元素及所有子元素:- 遇到
StartElement时输出元素名称,并递归处理其子元素 - 遇到
EndElement时跳出当前层级,返回上层继续遍历
- 遇到
- 增加文件打开失败的错误处理,以及XML解析错误的检查,提升代码健壮性
- 移除了无用的头文件(如
<iostream>、<QTextStream>)
运行修改后的代码即可得到期望的输出结果。
内容的提问来源于stack exchange,提问作者Сергей Малышев
相关产品推荐
相关产品推荐

