Почему этот код 4 раза ничего не выдает, а в пятый раз правильные данные?

Я получил XML-файл:

<weatherdata>
 <location>
  <name>Vlaardingen</name>
  <type/>
  <country>NL</country>
  <timezone/>
  <location altitude="0"
    latitude="51.912498"
    longitude="4.34167"
    geobase="geonames"
    geobaseid="2745467"/>
 </location>
 <credit/>
 <meta>
  <lastupdate/>
  <calctime>0.0152</calctime>
  <nextupdate/>
 </meta>
 <sun rise="2016-02-23T06:40:58"
   set="2016-02-23T17:11:47"/>
 <forecast>
  <time day="2016-02-23">
   <symbol number="500"
     name="lichte regen"
     var="10d"/>
   <precipitation/>
   <windDirection deg="316"
     code="NW"
     name="Northwest"/>
   <windSpeed mps="9.01"
     name="Fresh Breeze"/>
   <temperature day="6.06"
     min="5.57"
     max="6.06"
     night="5.66"
     eve="5.57"
     morn="6.06"/>
   <pressure unit="hPa"
     value="1027.72"/>
   <humidity value="96"
     unit="%"/>
   <clouds value="clear sky"
     all="8"
     unit="%"/>
  </time>
  <time day="2016-02-24">
   <symbol number="501"
     name="matige regen"
     var="10d"/>
   <precipitation value="3.15"
     type="rain"/>
   <windDirection deg="283"
     code="WNW"
     name="West-northwest"/>
   <windSpeed mps="6.21"
     name="Moderate breeze"/>
   <temperature day="4.98"
     min="4.17"
     max="5.11"
     night="4.17"
     eve="4.85"
     morn="4.32"/>
   <pressure unit="hPa"
     value="1030.97"/>
   <humidity value="100"
     unit="%"/>
   <clouds value="scattered clouds"
     all="48"
     unit="%"/>
  </time>
  <time day="2016-02-25">
   <symbol number="500"
     name="lichte regen"
     var="10d"/>
   <precipitation value="1.23"
     type="rain"/>
   <windDirection deg="295"
     code="WNW"
     name="West-northwest"/>
   <windSpeed mps="5.71"
     name="Moderate breeze"/>
   <temperature day="5.43"
     min="4.92"
     max="5.48"
     night="5.34"
     eve="5.48"
     morn="4.92"/>
   <pressure unit="hPa"
     value="1026.18"/>
   <humidity value="100"
     unit="%"/>
   <clouds value="broken clouds"
     all="68"
     unit="%"/>
  </time>
 </forecast>
</weatherdata>

Это мой код C++, который читает XML-файл:

#include <iostream>
#include <string>
#include "tinyxml2.h"

using namespace std;

struct weatherData
{
    // date of day
    string time_day;
    // symbol data for weathericon and display of weather type
    string symbol_number;
    string symbol_name;
    string symbol_var;
    // windspeed
    string windSpeed_mps;
    // min. and max. temperature
    string temp_min;
    string temp_max;
};


int main()
{
    weatherData forecast[3];

    int counter = 0;

    tinyxml2::XMLDocument doc;
    if(doc.LoadFile("daily.xml") == tinyxml2::XML_SUCCESS)
    {
        tinyxml2::XMLElement* root = doc.FirstChildElement();

        for(tinyxml2::XMLElement* elem = root->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement())
        {
            std::string elemName = elem->Value();

            for (tinyxml2::XMLElement* e = elem->FirstChildElement("time"); e != NULL; e = e->NextSiblingElement("time"))
            {

                if (e)
                {
                    const char *time = e->Attribute("day");

                    forecast[counter].time_day = time;
                    counter++;
                }


            }
            cout << "Time dates: " << endl;
            for (int i = 0; i < 3;i++)
            {
            cout << forecast[i].time_day << endl;
            }
            counter = 0;
        }
    }
}

Я новичок в кодировании. Я использую пример кода из блога и адаптировал его для своих нужд. Я знаю, что циклы for просто бегают по элементам в XML-файле. И каждый раз, когда он находит элемент "время", он смотрит, имеет ли он атрибут "день". Чего я не понимаю, так это того, почему он запускается 4 раза, а в пятый раз выдает атрибуты трех "временных" частей.

Это вывод:

Даты времени:

Даты времени:

Даты времени:

Даты времени:

Даты времени:

2016-02-23 2016-02-24 2016-02-25

1 ответ

Решение

Это потому, что ваш внешний цикл повторяется по всем прямым наследникам корневого элемента weatherdataт.е. он перебирает узлы элемента location, credit, meta, sun, а также forecast, Для каждого из этих элементов вы ищете time-элементы, в которых вы действительно заинтересованы. Но первые 4 элемента, т.е. location, credit, meta а также sun, не содержат никаких time-элемент, такой, что первые 4 итерации внешнего цикла не могут извлекать данные времени, тогда как 5-я итерация выбирает узел элемента forecast, который имеет три time-элементы, которые вы ищете.

Я полагаю, что это работает, если вы измените свой код следующим образом (обратите внимание на "forecast"-параметр в вызове FirstChildElement):

....
if(doc.LoadFile("daily.xml") == tinyxml2::XML_SUCCESS)
{
    tinyxml2::XMLElement* root = doc.FirstChildElement();

    for(tinyxml2::XMLElement* elem = root->FirstChildElement("forecast"); elem != NULL; elem = elem->NextSiblingElement())
    {
    ....
Другие вопросы по тегам