Я знаю, что, вероятно, мне здесь не хватает какой-то чрезвычайно очевидной вещи, но это сводит меня с ума уже несколько дней.
Вот простая функция, которую я написал, которая пока что должна найти первый тег в XML-документе:
void parse_weather_file(const char* weatherFileName, WeatherDataAsPWMValues *wd)
{
if (wd == NULL) return;
std::cout << weatherFileName << std::endl;
tinyxml2::XMLDocument doc(weatherFileName);
tinyxml2::XMLNode *root = doc.FirstChild();
if (root == NULL) std::cout << "Error" << std::endl;
}
Вот XML-документ, который я пытаюсь разобрать:
<!-- Sample output of openWeatherMap API -->
<?xml version = "1.0" encoding = "utf-8"?>
<current>
<city id = "2643741" name = "City of London">
<coord lon = "-0.09" lat = "51.51">
<country>GB</country>
<sun rise = "2015-06-30T03:46:57" set = "2015-06-30T20:21:12">
</city>
<temperature value = "72.34" min = "66.2" max = "79.88" unit = "fahrenheit"/>
<humidity value = "43" unit = "%">
<pressure value = "1020" unit = "hPa">
<wind>
<speed value = "7.78" name = "Moderate breeze">
<direction value = "140" code = "SE" name = "SouthEast">
</wind>
<clouds value = "0" name = "clear sky">
<visibility value = "10000">
<precipitation mode = "no">
<weather number = "800" value = "Sky is Clear" icon = "01d">
<lastupdate value = "2015-06-30T08:36:14">
</current>
И вот результат, который я получаю от функции:
test.xml
Error
Это предполагает, что root имеет значение NULL в конце функции, но я не уверен, почему это так.
@ zx485 Спасибо за ответ. К сожалению, эта ошибка все еще возникает даже с самозакрывающимися индикаторами на всех отдельных тегах.
Тогда ваш XML по-прежнему не правильно сформированный. Так что придется искать другие возможные ошибки. Я добавил ответ с версией хорошо сформированный вашего XML. Посмотрим, поможет ли это ...
@ zx485 Эта ошибка по-прежнему возникает со следующим XML-файлом: <test><content>Hello, world</content></test>
См. stackoverflow.com/questions/43285461/… для обсуждения FirstChild() по сравнению с FirstChildElement().





Я сделал ваш XML хорошо сформированный, добавив закрывающий / для отдельных элементов.
Вот как это выглядит:
<?xml version = "1.0" encoding = "utf-8"?>
<current>
<city id = "2643741" name = "City of London">
<coord lon = "-0.09" lat = "51.51" />
<country>GB</country>
<sun rise = "2015-06-30T03:46:57" set = "2015-06-30T20:21:12" />
</city>
<temperature value = "72.34" min = "66.2" max = "79.88" unit = "fahrenheit" />
<humidity value = "43" unit = "%" />
<pressure value = "1020" unit = "hPa" />
<wind>
<speed value = "7.78" name = "Moderate breeze" />
<direction value = "140" code = "SE" name = "SouthEast" />
</wind>
<clouds value = "0" name = "clear sky" />
<visibility value = "10000" />
<precipitation mode = "no" />
<weather number = "800" value = "Sky is Clear" icon = "01d" />
<lastupdate value = "2015-06-30T08:36:14" />
</current>
Надеюсь, это поможет вам выявить ошибки ...
Как объяснил @ zx485, ваш XML искажен. Но даже после исправления ваш код все равно не сработает. Согласно Документация TinyXML-2, класс tinyxml2::XMLDocument НЕ имеет конструктора, который принимает имя файла в качестве входных данных. Однако у него есть конструктор, который принимает bool в качестве входных данных:
XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
const char* неявно конвертируется в bool, поэтому ваш код компилируется, но на самом деле вы вообще не загружаете файл, поэтому root имеет значение NULL.
Вместо этого вам нужно вызвать метод класса LoadFile():
XMLError LoadFile( const char* filename );
Например:
void parse_weather_file(const char* weatherFileName, WeatherDataAsPWMValues *wd)
{
if (wd == NULL) return;
std::cout << weatherFileName << std::endl;
tinyxml2::XMLDocument doc;
XMLError err = doc.LoadFile(weatherFileName);
if (err != XML_SUCCESS) {
std::cout << "Error loading file: " << (int)err << std::endl;
/* or:
std::cout << "Error loading file: " << doc.ErrorName() << std::endl;
std::cout << "Error loading file: " << tinyxml2::XMLDocument::ErrorIDToName(err) << std::endl;
std::cout << "Error loading file: " << doc.ErrorStr() << std::endl;
std::cout << "Error loading file" <<< endl;
doc.PrintError();
*/
return;
}
tinyxml2::XMLNode *root = doc.FirstChild();
if (root == NULL) {
std::cout << "Error root is null" << std::endl;
return;
}
// use root as needed...
}
Кроме того, вы должны использовать метод RootElement() вместо метода FirstChild():
tinyxml2::XMLElement *root = doc.RootElement();
Ваш XML не хорошо сформированный. У вас отсутствуют закрывающие косые черты на отдельных элементах.
<lastupdate value = "2015-06-30T08:36:14">, например, должен быть<lastupdate value = "2015-06-30T08:36:14" />(<- см. Индикатор самозакрывания/).