簡體   English   中英

無法使用QXmlStreamReader識別空元素

[英]Cannot identify empty Elements with QXmlStreamReader

我在使用Qt QXmlStreamReader(Qt 4.8.1)檢測空元素時遇到一些麻煩。 有一個包含以下部分的XML文件

<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進行的解析代碼,我對其進行了簡化,因此可能無法編譯。 只是您了解了基本思想。

[...]
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元素。 似乎解析器只能檢測

<tag></tag>

作為一個空元素,但不是

<tag/>

那么,僅僅是我還是Qt中存在問題? 如果是這樣,如何檢測不包含2個單獨元素(開始/結束)的空元素?

編輯:因此,休伊特(Huytard)要求我提供一個可行的示例。 但是他的回答使我找到了一個幾乎可以回答我問題的解決方案。 因此,我在回答中舉了一個明確的例子。

因此,感謝Huytard,我意識到這只是QXmlStreamReader :: readNextStartElement的行為,這在某種程度上是出乎意料的。 我所期望的是,它實際上只會讀取開始元素。 最初,我想事先檢查一個元素是否為空,然后決定如何處理其內容。 看來這是不可能的。 我自己引用的文檔涵蓋了這種可能性。 即,即使一個原子元素為空,它實際上也會跟隨一個開始元素,而實際上是一個結束元素。 那樣不好,因為您無法返回流。

根據他的回答,我寫了一個小例子,既澄清了(抱歉)又回答了我的原始問題。

  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;
  }

這導致以下輸出

  #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

我還是不喜歡 我需要對所有工作進行三重檢查,以使代碼的可讀性降低。

您是否已通過調試器運行了此程序?

我的直覺是您的代碼中存在錯誤-因此發布代碼的完整且相關的部分將有助於排除這是Qt錯誤的可能性(我敢打賭不是)。

下面的簡短測試應確認QXmlStreamReader可以解析一個空元素:

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;
}

輸出:

Using readNextStartElement(): 
"root" 
"node" 
"node" 
"root" 
"" 
Using readNext(): 
"" 
"root" 
"node" 
"node" 
"root" 
"" 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM