Простой парсинг XML в Qt

от автора

Достаточно часто в проекте нужно создать конфигурацию, которую можно легко изменять без перекомпилирования.

Особенно, если эта программа управляет неким устройством, и необходимо создать действовать в зависимости от состояния устройства или же через какое то время. Тут на помощь приходит XML.

Есть простой xml-конфиг:

<?xml version="1.0" encoding="UTF-8" ?> <etaps> 	<etap id="1"> 		<name>Первый</name> 		<firststage>1</firststage> 		<laststage>9</laststage> 		<pausestage>10</pausestage>         <etappause>5</etappause> 	</etap> 	<etap id="2"> 		<name>Второй</name> 		<firststage>10</firststage> 		<laststage>20</laststage> 		<pausestage>15</pausestage>         <etappause>2</etappause> 	</etap> 	<etap id="3"> 		<name>Последний</name> 		<firststage>21</firststage> 		<laststage>50</laststage> 		<pausestage>15</pausestage>         <etappause>3</etappause> 	</etap> </etaps> 

Задача: распарсить простой файл средствами Qt, а именно QXmlStreamReader.

Открываем конфиг:

    QFile* file = new QFile("config.xml");      if (!file->open(QIODevice::ReadOnly | QIODevice::Text))     {         emit Log(tr("Невозможно открыть XML-конфиг"), LOG_LEVEL_ERROR);         return false;     }     QXmlStreamReader xml(file); 

Ищем нужный тег (etaps) и находим вложенный тег etap:

    while (!xml.atEnd() && !xml.hasError())     {         QXmlStreamReader::TokenType token = xml.readNext();         if (token == QXmlStreamReader::StartDocument)             continue;         if (token == QXmlStreamReader::StartElement)         {             if (xml.name() == "etaps")                 continue;             if (xml.name() == "etap")                 XMLConf.append(parseEtap(xml));         }     } 

парсим внутри тега etap и добавляем все в QMap<QString, QString>:

проверяем, там ли мы находимся:

    QMap<QString, QString> etap;     if (xml.tokenType() != QXmlStreamReader::StartElement && xml.name() == "etap")         return etap; 

парсим каждый вложенный в etap тег и добавляем в QMap:

    QXmlStreamAttributes attributes = xml.attributes();     if (attributes.hasAttribute("id"))         etap["id"] = attributes.value("id").toString();     xml.readNext();     while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "etap"))     {         if (xml.tokenType() == QXmlStreamReader::StartElement)         {             if (xml.name() == "name")                 addElementDataToMap(xml, etap);             if (xml.name() == "firststage")                 addElementDataToMap(xml, etap);             if (xml.name() == "laststage")                 addElementDataToMap(xml, etap);             if (xml.name() == "pausestage")                 addElementDataToMap(xml, etap);             if (xml.name() == "etappause")                 addElementDataToMap(xml, etap);         }         xml.readNext();     } 

добавление в QMap

void addElementDataToMap(QXmlStreamReader& xml, QMap<QString, QString>& map) const {     if (xml.tokenType() != QXmlStreamReader::StartElement)         return;     QString elementName = xml.name().toString();     xml.readNext();     map.insert(elementName, xml.text().toString()); }  

В итоге мы получаем QMap<QString, QString> с несколькими элементами, в каждом из которых две строки: название тега и его значение.

ссылка на оригинал статьи https://habr.com/ru/post/532436/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *