首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法用QXmlStreamReader标识空元素

无法用QXmlStreamReader标识空元素
EN

Stack Overflow用户
提问于 2014-01-22 10:45:11
回答 2查看 2.1K关注 0票数 1

我在使用Qt QXmlStreamReader (QT4.8.1)检测空元素时遇到了一些问题。有一个XML文件包含以下部分

代码语言:javascript
复制
<Groups Number="4">
  <Group Id="0" GroupName="Chambers">
    <MemberChannels>4,5,6,7,8,9,10,11</MemberChannels>
    <AverageShown>true</AverageShown>
  </Group>
  <Group Id="1" GroupName="Fluids">
    <MemberChannels>0,1,17,18</MemberChannels>
    <AverageShown>false</AverageShown>
  </Group>
  <Group Id="2"/>
  <Group Id="3"/>
</Groups>

如您所见,除了属性之外,Id 2和3的元素都是空的。属性不会改变任何东西。如果它不在元素中,问题仍然会发生。

这是使用QXmlStreamReader进行解析的代码,我对其进行了简化,因此它可能无法编译。只是你有了基本的想法。

代码语言:javascript
复制
[...]
QXmlStreamReader* m_poStreamReader = new QXmlStreamReader;
[...]

if(m_poStreamReader->readNextStartElement() && m_poStreamReader->name().toString() == "Group") {
  this->parseGroupElement();
}

[...]

bool CTempscanXmlParser::parseGroupElement( void ) {
  TGroupElement tElement;
  if(m_poStreamReader->isStartElement() && !m_poStreamReader->isEndElement()) { // not empty
    TGroupElement tElement = this->readGroupElement();
  } else if(m_poStreamReader->isStartElement() && m_poStreamReader->isEndElement()) { // empty
    tElement.oGroupName = QString::null;
  }
  [...]
}

文件上说:

空元素也被报告为StartElement,后面是EndElement。

我可以使用readNext(),但仍然没有接收到end元素。似乎解析器只能检测到

代码语言:javascript
复制
<tag></tag>

作为一个空元素,但不是

代码语言:javascript
复制
<tag/>

那么,是我的问题还是Qt中存在的问题?如果是这样的话,如何检测不包含两个独立元素(开始/结束)的空元素?

编辑:所以Huytard问我一个有用的例子。但他的回答让我找到了一个几乎回答了我问题的解决方案。因此,我在答覆中举出一个明确的例子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-23 08:59:42

因此,多亏了Huytard,我才意识到这只是QXmlStreamReader::readNextStartElement的行为,这在某种程度上是出乎意料的。我所期望的是,它实际上只会读取start元素。最初,我想事先检查元素是否为空,然后决定如何处理其内容。看来这是不可能的。而我引用的文件也涵盖了这种不可能的情况。也就是说,即使一个原子元素是空的,它实际上是一个开始元素,它实际上是一个结束元素。这很糟糕,因为你不能回到小溪里去。

基于他的回答,我写了一个小例子,既澄清了(对不起),又回答了我最初的问题。

代码语言:javascript
复制
  const QString XML_STR = "<Groups Number=\"4\">" \
                          "<Group Id=\"0\" GroupName=\"Chambers\">" \
                          "<MemberChannels>4,5,6,7,8,9,10,11</MemberChannels>" \
                          "<AverageShown>true</AverageShown>" \
                          "</Group>" \
                          "<Group Id=\"1\"/>" \
                          "<Group Id=\"2\"/>" \
                          "</Groups>";

  int main(int /* argc */, char** /* argv[] */)
  {

     qDebug() << "the way it would have made sense to me:";
     {
        QXmlStreamReader reader(XML_STR);

        while(!reader.atEnd())
        {
           reader.readNextStartElement();
           QString comment = (reader.isEndElement()) ? "is empty" : "has children";
           qDebug() << reader.name() << comment;
        }
     }

    qDebug() << "\napproximation to the way it should probably be done:";
    {
       QXmlStreamReader reader(XML_STR);

       bool gotoNext = true;
       while(!reader.atEnd())
       {
          if(gotoNext) {
             reader.readNextStartElement();
          }
          QString output = reader.name().toString();
          reader.readNext();
          if(reader.isEndElement()) {
             output += " is empty";
             gotoNext = true;
          } else {
             output += " has children";
             gotoNext = false;
          }
          qDebug() << output;
       }
    }

    return 0;
  }

,这将导致以下输出

代码语言:javascript
复制
  #they way it would have made sense to me: 
  "Groups" "has children" 
  "Group" "has children" 
  "MemberChannels" "has children" 
  "MemberChannels" "is empty" 
  "AverageShown" "has children" 
  "AverageShown" "is empty" 
  "Group" "is empty" 
  "Group" "has children" 
  "Group" "is empty" 
  "Group" "has children" 
  "Group" "is empty" 
  "Groups" "is empty" 
  "" "has children"
  # this has all been plain wrong

  #approximation to the way it should probably be done: 
  "Groups has children" 
  "Group has children" 
  "MemberChannels has children" 
  " is empty"           # ... but not a start element
  "AverageShown has children" 
  " is empty" 
  "Group has children"  # still wrong! this is an end element
  "Group is empty" 
  "Group is empty" 
  "Groups has children" # ditto

我还是不喜欢。按照我的工作方式,我需要对每件事情进行三次检查,这会降低代码的可读性。

票数 1
EN

Stack Overflow用户

发布于 2014-01-22 18:28:05

你用调试器运行过这个过程吗?

我的直觉是,您的代码中有一个bug -所以发布完整的和代码的相关部分将有助于排除这是Qt错误的可能性(我敢打赌它不是)。

下面这个简短的测试应该确认QXmlStreamReader可以解析一个空元素:

代码语言:javascript
复制
const QString XML_STR = "<root><node /></root>";

int main(int /* argc */, char* /* argv[] */)
{

  qDebug() << "Using readNextStartElement():";
  {
    QXmlStreamReader reader(XML_STR);

    while(!reader.atEnd())
    {
      reader.readNextStartElement();
      qDebug() << reader.name();
    }
  }

  qDebug() << "Using readNext():";
  {
    QXmlStreamReader reader(XML_STR);

    while(!reader.atEnd())
    {
      reader.readNext();
      qDebug() << reader.name();
    }
  }

  return 0;
}

产出:

代码语言:javascript
复制
Using readNextStartElement(): 
"root" 
"node" 
"node" 
"root" 
"" 
Using readNext(): 
"" 
"root" 
"node" 
"node" 
"root" 
"" 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21280705

复制
相关文章

相似问题

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