Достаточно часто в проекте нужно создать конфигурацию, которую можно легко изменять без перекомпилирования.
Особенно, если эта программа управляет неким устройством, и необходимо создать действовать в зависимости от состояния устройства или же через какое то время. Тут на помощь приходит 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/
Добавить комментарий