问题 如何在Qt中使用带有QDomNodeList的foreach?


我是Qt的新手,我每天都在学习新东西。
目前,我正在空闲时间为我的诺基亚N900开发一个小应用程序。
一切都很好,我能够在设备上编译和运行Maemo应用程序。

我刚学会了这个 foreach Qt中的关键字(我知道它不是用C ++编写的,所以直到我偶然发现一个提到它的Qt文档时我才考虑它。)
所以,我决定将我那令人烦恼且难以理解的循环改为foreach,但我对此失败了:

QDomNodeList list = doc.lastChild().childNodes().at(1).firstChild().childNodes();
for (int x = 0; x < list.count(); x++)
{
    QDomElement node = list.at(x).toElement();
    // Do something with node
}

这是我尝试的方式:

foreach (QDomElement node, doc.lastChild().childNodes().at(1).firstChild().childNodes())
{
    // Do something with node
}

由于某种原因,上面的代码甚至没有编译。我从编译器得到了神秘的错误消息。

有人可以向我解释如何正确吗?

如果 foreach 循环不支持 QDomNodeList,有没有办法处理支持的XML文件 foreach

编辑:

澄清, // Do something with node 在这种情况下是以下内容:

EveCharacter chr;
chr.setName(node.attribute(EVE_NAME));
chr.setId(node.attribute(EVE_CHARACTER_ID).toInt());
acc->addCharacter(chr);

acc是类型的 EveAccount,将数据存储在 QList<EveCharacter>

大写符号是编译时常量字符串。
(我正在为EVE Online API创建一个客户端。这来自接收的方法 帐户字符XML 并解释它。)

这就是我创造的方式 doc

QDomDocument doc;
doc.setContent(reply->readAll());

注意 reply 是一个 QNetworkReply* 这是从一个发回来的 QNetworkAccessManager

但是,由于EVE API与XML一起工作,我在我的应用程序的许多地方做了很多非常类似的XML解析。
大多数XML可以长达数百行,并且可以包含非常规的数据模式, 比如这个


9698
2018-05-26 15:57


起源

另外,你得到一个神秘信息的原因是因为 foreach  实际上不是关键字,它是一个宏。因为C ++不支持语法,所以Qt必须做一些聪明的预处理器工作才能使它工作。这意味着任何编译器消息都将用于与您看到的代码看起来不太相似的代码。 - Skilldrick
@Skilldrick - 谢谢你的解释! - Venemo


答案:


foreach 只支持 容器类,所以你不能用它 QDomNodeList

我不确定你的实际目标,但我找到了 QXmlSimpleReader 和 QXmlStreamReader 是处理XML的最简单方法。

编辑以匹配问题编辑:

你想做的事情看起来像是XPath或XQuery的主要候选者。看看吧 QtXmlPatterns 这将为您提供一组字符节点,而无需遍历所有其他节点。


8
2018-05-26 16:15



@Adam - 我阅读了您链接的文档,但我无法理解如何正确使用它们。我看不到它们在DOM树中导航的方法。能否请您使用我的相应代码 QXmlSimpleReader 和 QXmlStreamReader? - Venemo
当然,如果你提供 // Do something with node - Adam W
我会更清楚。如果您只是阅读或编写XML文件,那么这些文件非常有效。如果您尝试将XML用作数据库并且不想使用XQuery或XPath(不确定为什么要这样做),则需要 QDomDocument。 - Adam W
@Adam - 我添加了代码 // Do something with node,以及关于我需要用它实现什么的更多解释以及关于我需要解析什么XML的一些链接。 - Venemo
@Adam - 只是一个小贴士:如果你开始发帖 @Venemo,SO会通知我,我有新的回复。 :) - Venemo


foreach 与...合作 Qt通用容器。它看起来不像 QDomNodeList 从任何东西继承,所以你不能使用 foreach

你可以遍历节点列表并将节点插入到 QList<QDomElement>


2
2018-05-26 16:06



您链接到容器的4.2文档但该类的4.6文档的任何原因? :) - Adam W
我可以,但我没有看到有两个循环而不是一个... - Venemo
@Adam - 我发布后很快就改变了它 - 这正是Google带来的!我发现你使用Google上的第一个结果获得哪些文档非常随意...... - Skilldrick
@Venemo--足够公平。那么,你只需要使用一个丑陋的循环。 - Skilldrick
很抱歉听到这个消息。无论如何,谢谢你的回答! - Venemo