QXmlStreamReader 解析指南
QXmlStreamReader 解析指南
1.分级负责制
不要在一个循环里处理所有层级的节点。最稳健的架构是“父节点驱动步进,子节点闭环消耗”。
-
第一层(主循环): 负责使用 readNextStartElement() 寻找业务大块(如 ROI 节点)。
-
第二层(业务分发): 识别是大块 A 还是大块 B,调用相应的解析函数。
-
第三层(具体解析): 先读属性,再用内部 while 循环处理嵌套子节点,并确保离开时游标已对齐。
2.关键 API 的规则
在处理 XML 流解析时,理解游标(Cursor)的移动逻辑是避免死循环和跳节点的关键。
| API 方法 | 游标行为 (Cursor Behavior) | 典型用途 (Use Case) |
|---|---|---|
attributes() |
原地不动。仅读取当前标签头部的属性列表。 | 在进入 while 循环解析子节点前,获取父标签自带的配置参数。 |
readNextStartElement() |
主动步进。自动跳过换行符、空白字符和注释,停在下一个 <StartElement>。若遇到当前层级的 </EndElement> 则返回 false。 |
驱动循环的核心引擎。能自动处理 XML 复杂的缩进格式,确保逻辑始终指向下一个有效标签。 |
skipCurrentElement() |
快速对齐。将游标从当前 StartElement 直接移向匹配的 EndElement 之后。 | 处理完某个子节点后,确保游标跳出该节点内部,为主循环读取下一个兄弟节点做准备。 |
name() |
仅读取。获取当前游标所在标签的名称。 | 用于 if/else 或 switch 分支判断,确定当前走哪条业务逻辑。 |
isStartElement() |
仅读取。判断当前游标是否指向一个开始标签。 | 常用于进入解析函数时的安全检查。 |
3. 嵌套节点解析模板(万能公式)
当你遇到一个既带属性又有子节点的元素时,请直接套用此结构:
// [进入函数时] 游标位于 <ParentNode ...>
if (xmlReader.isStartElement() && xmlReader.name() == "ParentNode")
{
// 1. 获取当前节点属性(此时游标并未移动)
auto attrs = xmlReader.attributes();
int val = attrs.value("attr").toInt();
// 2. 遍历子节点(readNextStartElement 会把游标推入 ParentNode 内部)
while (xmlReader.readNextStartElement())
{
// 直接获取到<StartElement>
QString subName = xmlReader.name().toString();
if (subName == "SubNode") {
// 解析子节点...
xmlReader.skipCurrentElement(); // [关键] 处理完后跳出子节点
}
else {
xmlReader.skipCurrentElement(); // [关键] 容错,跳过不认识的子项
}
}
// [退出函数时] while 循环因撞上 </ParentNode> 而停止,游标停在结束标签上
}

浙公网安备 33010602011771号