我一直在尝试从此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 4.7.2 SDK直接来自Qt网站,QtCreator 2.3.1在Windows和Linux上(在这种特殊情况下没有任何区别,结果是相同的)。我想确定这是我缺乏知识的问题,而不是软件错误,请帮助
答案 0 :(得分:8)
不幸的是,从Qt文档中不清楚,如果你想使用QXmlQuery::setFocus(const QXmlItem& item)
重载来查询子节点,你应该使用QXmlQuery
构造函数创建相应的QXmlQuery(const QXmlNamePool& np)
个对象。让他们共享相同的QXmlNamePool
对象。简而言之,这种共享将查询相互关联。
考虑到这一点,您的示例应如下所示:
QFile structure("./structure.xml");
structure.open(QFile::ReadOnly);
QXmlQuery query;
query.setFocus(&structure);
query.setQuery("data/x");
QXmlResultItems results;
query.evaluateTo(&results);
QXmlQuery childQuery(query.namePool());
while (!results.next().isNull()) {
childQuery.setFocus(results.current());
childQuery.setQuery("nam/text()");
QString r;
childQuery.evaluateTo(&r);
qDebug() << r;
}
此外,您可以进一步重用初始QXmlQuery
对象:
QFile structure("./structure.xml");
structure.open(QFile::ReadOnly);
QXmlQuery query;
query.setFocus(&structure);
query.setQuery("data/x");
QXmlResultItems results;
query.evaluateTo(&results);
while (!results.next().isNull()) {
query.setFocus(results.current());
query.setQuery("nam/text()");
QString r;
query.evaluateTo(&r);
qDebug() << r;
}
答案 1 :(得分:1)
而不是使用evaluateTo( QString * )
使用QStringList
版本。它应该工作。
答案 2 :(得分:0)
它应该像这样工作:
QDomDocument doc("structure");
QFile file("structure.xml");
if( !file.open( IO_ReadOnly ) )
return -1;
if( !doc.setContent( &file ) )
{
file.close();
return -2;
}
file.close();
QDomElement root = doc.documentElement();
if( root.tagName() != "data" )
return -3;
QDomNode n = root.firstChild();
while( !n.isNull() )
{
QDomElement e = n.toElement();
if( !e.isNull() )
{
if( e.tagName() == "x" )
{
QMessageBox::information( 0, "X", e.attribute("id", "")+ "\n" + e.attribute("nam", "" ) + "\n" + e.attribute("tab", ""));
}
}
n = n.nextSibling();
}
代码正在为每个x做一个消息框(在这台机器上没有qt,所以现在无法测试它)
答案 3 :(得分:0)
我遇到了同样的问题,解决方法是让query
和childQuery
完全相同。您可以将代码重写为:
while(!next.isNull()) {
qDebug() << next.toNodeModelIndex().stringValue();
QString r;
query.setFocus(next);
query.setQuery("./nam/text()");
query.evaluateTo(&r);
qDebug() << r;
next = results.next();
}
如果childQuery
在另一个程序中,则必须通过引用传递它。