使用Qt的QXmlStreamReader解析QString格式XML的技术问询
使用QXmlStreamReader解析指定格式的XML字符串
刚好我之前也用QXmlStreamReader处理过类似的XML解析需求,给你分享一下具体的实现步骤和代码示例吧!你的XML是包裹在<unit>根节点下的一组平级子节点,都是简单的键值对结构,用QXmlStreamReader这种流式解析器来处理非常高效。
实现步骤
- 初始化解析器:把QString类型的XML内容传入QXmlStreamReader,无需额外预处理(只要XML格式合法)。
- 遍历节点循环:通过
readNext()逐个读取XML节点,跳过无关的文档声明、空白节点,只处理起始元素节点。 - 提取字段值:判断每个起始元素的名称,用
readElementText()直接获取对应文本内容,自动跳过结束元素。 - 错误捕获:解析过程中检查是否有格式错误,及时输出调试信息。
完整代码示例
#include <QXmlStreamReader> #include <QString> #include <QDebug> // 定义结构体存储解析结果,方便后续使用 struct UnitInfo { QString unitType; QString manufacturer; QString articleNumber; QString productionDate; QString deliveryRevision; QString presentRevision; QString revDate; QString madeTheLastRev; QString serialNumber; }; UnitInfo parseUnitXml(const QString& xmlStr) { UnitInfo info; QXmlStreamReader reader(xmlStr); while (!reader.atEnd() && !reader.hasError()) { QXmlStreamReader::TokenType token = reader.readNext(); // 跳过文档开头的声明节点 if (token == QXmlStreamReader::StartDocument) { continue; } // 处理起始元素节点 if (token == QXmlStreamReader::StartElement) { QString elemName = reader.name().toString(); if (elemName == "unit_type") { info.unitType = reader.readElementText(); } else if (elemName == "manufacturer") { info.manufacturer = reader.readElementText(); } else if (elemName == "article_number") { info.articleNumber = reader.readElementText(); } else if (elemName == "production_date") { info.productionDate = reader.readElementText(); } else if (elemName == "delivery_revision") { info.deliveryRevision = reader.readElementText(); } else if (elemName == "present_revision") { info.presentRevision = reader.readElementText(); } else if (elemName == "rev_date") { info.revDate = reader.readElementText(); } else if (elemName == "made_the_last_rev") { info.madeTheLastRev = reader.readElementText(); } else if (elemName == "serial_number") { info.serialNumber = reader.readElementText(); } // 后续新增节点直接添加else if分支即可 } } // 检查解析错误 if (reader.hasError()) { qDebug() << "XML解析出错:" << reader.errorString(); } reader.clear(); return info; } // 使用示例 int main() { QString xmlContent = "<unit> <unit_type>110A</unit_type> <manufacturer>ABC</manufacturer> <article_number>9900</article_number> <production_date>2008-05-29</production_date> <delivery_revision>03B</delivery_revision> <present_revision>03B</present_revision> <rev_date>2008-05-29</rev_date> <made_the_last_rev>B21</made_the_last_rev> <serial_number>530029</serial_number></unit>"; UnitInfo unit = parseUnitXml(xmlContent); // 打印解析结果 qDebug() << "设备类型:" << unit.unitType; qDebug() << "制造商:" << unit.manufacturer; qDebug() << "产品编号:" << unit.articleNumber; qDebug() << "生产日期:" << unit.productionDate; qDebug() << "交付版本:" << unit.deliveryRevision; qDebug() << "当前版本:" << unit.presentRevision; qDebug() << "版本日期:" << unit.revDate; qDebug() << "最后版本制作方:" << unit.madeTheLastRev; qDebug() << "序列号:" << unit.serialNumber; return 0; }
关键细节说明
readElementText():这个方法非常实用,调用后会自动读取当前起始元素的文本内容,并跳转到对应的结束元素,省去了手动处理文本节点和结束节点的麻烦。- 流式解析优势:QXmlStreamReader不需要把整个XML加载到内存中,对于大体积的XML也能高效处理,你的场景虽然内容不多,但这种写法扩展性很强。
- 容错处理:如果XML中缺少某个节点,对应的结构体字段会是空字符串,你可以根据需求添加默认值或者缺失提示。
内容的提问来源于stack exchange,提问作者JNI_OnLoad




