首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用QXmlItem作为QXmlQuery焦点提取子节点值

使用QXmlItem作为QXmlQuery焦点提取子节点值
EN

Stack Overflow用户
提问于 2011-10-17 23:38:42
回答 4查看 3.7K关注 0票数 7

我一直在尝试从这个XML文件中获取节点文本值:

代码语言:javascript
复制
  <!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是空的。我使用这段代码:

代码语言:javascript
复制
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.2SDK,Windows和Linux上的QtCreator 2.3.1 (在这种情况下没有任何区别,结果是相同的)。我想确定这是我缺乏知识的问题,而不是软件错误,请帮助我

EN

回答 4

Stack Overflow用户

发布于 2014-11-25 10:31:00

不幸的是,Qt文档并不清楚,当您想要使用QXmlQuery::setFocus(const QXmlItem& item)重载来查询子节点时,您应该使用QXmlQuery(const QXmlNamePool& np)构造函数创建相应的QXmlQuery对象,使它们共享相同的QXmlNamePool对象。简单地说,这种共享将查询彼此关联起来。

考虑到这一点,您的示例应该如下所示:

代码语言:javascript
复制
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对象:

代码语言:javascript
复制
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;
}
票数 8
EN

Stack Overflow用户

发布于 2012-03-04 21:19:05

使用QStringList版本而不是evaluateTo( QString * )。应该能行得通。

票数 1
EN

Stack Overflow用户

发布于 2011-10-17 23:57:31

它应该是这样工作的:

代码语言:javascript
复制
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,所以现在不能测试它)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7796126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档