以 QXmlItem 作为 QXmlQuery 焦点提取子节点值
我一直在尝试从这个 XML 文件中获取节点文本值:
<!DOCTYPE structure>
<data>
<x>
<id>1</id>
<nam>tytuł</nam>
<tab>21</tab>
<ind>5</ind>
<pre>TY</pre>
<khw>C.TY</khw>
</x>
<x>
<id>2</id>
<nam>autor</nam>
<tab>21</tab>
<ind>5</ind>
<pre>FO</pre>
<khw>C.FO</khw>
</x>
<x>
<id>3</id>
<nam>hasło korporatywne</nam>
<tab>21</tab>
<ind>5</ind>
<pre>FN</pre>
<khw>C.FN</khw>
</x>
</data>
我想要做的是获取每个节点及其子节点并将其转换为 QMap。我在获取单个元素方面没有任何问题,但是当通过将 QXmlQuery 的结果设置为焦点来获取子项时,我评估子节点查询的 QString 为空。我使用这段代码:
QXmlResultItems results;
QFile structure("./structure.xml"); // xml file, as described earlier
structure.open(QFile::ReadOnly);
QXmlQuery query;
query.setFocus(&structure);
query.setQuery("data/x");
query.evaluateTo(&results);
QXmlItem next = results.next();
while(!next.isNull()) {
qDebug() << next.toNodeModelIndex().stringValue(); // everything's fine. It prints contents of <x>'s child nodes
QXmlQuery childQuery;
QString r;
childQuery.setFocus(next);
childQuery.setQuery("./nam/text()"); // already tested: "/nam/text()", "/nam/string()", "x/nam/string()", "data/x/nam/string()" etc... still no luck.
childQuery.evaluateTo(&r);
qDebug() << r; // prints \n but it should print content of <nam> node.
next = results.next();
}
我使用的软件:直接来自Qt网站的Qt 4.7.2 SDK,Windows和Linux上的QtCreator 2.3.1(在这种特殊情况下没有任何区别,结果是相同的)。我想确定这是我缺乏知识的问题,而不是软件错误,请帮忙
I've been trying to fetch node text values from this XML file:
<!DOCTYPE structure>
<data>
<x>
<id>1</id>
<nam>tytuł</nam>
<tab>21</tab>
<ind>5</ind>
<pre>TY</pre>
<khw>C.TY</khw>
</x>
<x>
<id>2</id>
<nam>autor</nam>
<tab>21</tab>
<ind>5</ind>
<pre>FO</pre>
<khw>C.FO</khw>
</x>
<x>
<id>3</id>
<nam>hasło korporatywne</nam>
<tab>21</tab>
<ind>5</ind>
<pre>FN</pre>
<khw>C.FN</khw>
</x>
</data>
What I want to do is to fetch every node and it's children and convert it to QMap. I have no trouble with fetching single element, but when it comes to fetch children items by setting result of QXmlQuery as a focus, the QString that i evaluate the child node query is empty. I use this piece of code:
QXmlResultItems results;
QFile structure("./structure.xml"); // xml file, as described earlier
structure.open(QFile::ReadOnly);
QXmlQuery query;
query.setFocus(&structure);
query.setQuery("data/x");
query.evaluateTo(&results);
QXmlItem next = results.next();
while(!next.isNull()) {
qDebug() << next.toNodeModelIndex().stringValue(); // everything's fine. It prints contents of <x>'s child nodes
QXmlQuery childQuery;
QString r;
childQuery.setFocus(next);
childQuery.setQuery("./nam/text()"); // already tested: "/nam/text()", "/nam/string()", "x/nam/string()", "data/x/nam/string()" etc... still no luck.
childQuery.evaluateTo(&r);
qDebug() << r; // prints \n but it should print content of <nam> node.
next = results.next();
}
Software I use: Qt 4.7.2 SDK directly from Qt website, QtCreator 2.3.1 on Windows and Linux (without any difference in this particular case, results are the same). I want to be sure that's the problem of my lack of knowledge, rather than software bug, please help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不幸的是,从 Qt 文档中不清楚,当您想要使用 QXmlQuery::setFocus(const QXmlItem& item) 重载来查询子节点时,您应该创建相应的 QXmlQuery< /code> 对象使用
QXmlQuery(const QXmlNamePool& np)
构造函数使它们共享相同的QXmlNamePool
对象。简而言之,这种共享将查询相互关联起来。考虑到这一点,您的示例应如下所示:
此外,您可以进一步重用初始
QXmlQuery
对象:Unfortunately, it is unclear from Qt Documentation that in cases when you want to use
QXmlQuery::setFocus(const QXmlItem& item)
overload in order to query child nodes, you should create correspondingQXmlQuery
objects usingQXmlQuery(const QXmlNamePool& np)
constructor to make them share the sameQXmlNamePool
object. Such sharing, simply speaking, relates queries to each other.Considering this, your example should look like following:
Moreover, you can go further and reuse initial
QXmlQuery
object:请使用
QStringList
版本,而不是使用evaluateTo( QString * )
。它应该有效。Instead of using
evaluateTo( QString * )
use theQStringList
version. It should work.它应该像这样工作:
代码正在为每个 x 执行一个消息框(这台机器上没有 qt,所以现在无法测试它)
It should work like this:
The code is doing a message box for every x (don't have qt on this machine, so can't test it right now)
我遇到了同样的问题,解决方案是让
query
和childQuery
完全相同。您可以将代码重写为:如果
childQuery
位于另一个过程中,则必须通过引用传递它。I had the same problem, and the solution was to have the
query
andchildQuery
be exactly the same. You could rewrite your code as :if
childQuery
is to be in another procedure, you have to pass it by reference.