You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

使用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

火山引擎 最新活动