XML-Based Configuration Storage Using QDomDocument in Qt

Qt Configuration Storage with XML

Qt provides comprehensive libraries for application development, including configuration menagement capabilities. While QSettings handles INI file operations effectively, certain limitations may necessitate alternative approaches. This implemantation demonstrates using XML files as configuration storage through Qt's QDomDocument class.

QSettings Limitations

QSettings offers straightforward INI file operations but has several constraints:

  • Encoding issues with specific character sets
  • Inability to use Chinese characters as keys
  • Encoding conflicts when multiple QSettings instances are created in nested scopes

XML Document Structure

The XML structure mimics INI file organization with groups and items:

<groups>
  <group name="General">
    <item name="username">admin</item>
    <item name="language">English</item>
  </group>
</groups>

XML Configuration Handler Implementation

Reading XML Configuration

void XmlConfigHandler::loadConfiguration(const QString &configPath)
{
    if(configPath.isEmpty()) return;
    
    QFile configFile(configPath);
    if(!configFile.open(QFile::ReadOnly | QFile::Text)) return;
    
    QDomDocument xmlDoc;
    QString parseError;
    int errorLine, errorColumn;
    if(!xmlDoc.setContent(&configFile, false, &parseError, &errorLine, &errorColumn)) {
        configFile.close();
        return;
    }
    
    if(xmlDoc.isNull()) {
        configFile.close();
        return;
    }
    
    m_configData.clear();
    
    QDomElement root = xmlDoc.documentElement();
    QDomNodeList sections = root.childNodes();
    for(int i = 0; i < sections.count(); ++i) {
        QDomNode sectionNode = sections.item(i);
        QDomElement sectionElement = sectionNode.toElement();
        QString sectionName = sectionElement.attribute("name");
        
        QMap<QString, QString> parameters;
        QDomNodeList paramList = sectionElement.childNodes();
        for(int j = 0; j < paramList.count(); ++j) {
            QDomNode paramNode = paramList.item(j);
            QDomElement paramElement = paramNode.toElement();
            QString paramName = paramElement.attribute("name");
            QString paramValue = paramElement.text();
            
            if(paramName.isEmpty()) {
                parameters[QString::number(j)] = paramValue;
            } else {
                parameters[paramName] = paramValue;
            }
        }
        m_configData[sectionName] = parameters;
    }
    configFile.close();
}

Saving XML Configuration

void XmlConfigHandler::saveConfiguration(const QString &configPath)
{
    QDomDocument xmlDoc;
    QString xmlHeader("version=\"1.0\" encoding=\"UTF-8\"");
    xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", xmlHeader));
    
    QDomElement rootElement = xmlDoc.createElement("groups");
    xmlDoc.appendChild(rootElement);
    
    for(auto sectionIter = m_configData.begin(); sectionIter != m_configData.end(); ++sectionIter) {
        QDomElement sectionNode = xmlDoc.createElement("group");
        sectionNode.setAttribute("name", sectionIter.key());
        
        QMap<QString, QString> sectionParams = sectionIter.value();
        for(auto paramIter = sectionParams.begin(); paramIter != sectionParams.end(); ++paramIter) {
            QString paramKey = paramIter.key();
            QString paramValue = paramIter.value();
            
            QDomElement paramNode = xmlDoc.createElement("item");
            paramNode.setAttribute("name", paramKey);
            
            QDomText valueNode = xmlDoc.createTextNode(paramValue);
            paramNode.appendChild(valueNode);
            
            sectionNode.appendChild(paramNode);
        }
        rootElement.appendChild(sectionNode);
    }
    
    QFile outputFile(configPath);
    if(outputFile.open(QFile::WriteOnly | QFile::Text)) {
        QTextStream fileStream(&outputFile);
        xmlDoc.save(fileStream, 4);
        outputFile.close();
    }
}

Addding Configuration Items

bool XmlConfigHandler::insertParameter(const QString &value, const QString &section, const QString &key)
{
    if(value.isEmpty() || section.isEmpty()) return false;
    
    if(key.isEmpty()) {
        int paramCount = m_configData[section].size();
        m_configData[section][QString::number(paramCount)] = value;
    } else {
        m_configData[section][key] = value;
    }
    
    saveConfiguration(m_configFilePath);
    return true;
}

Removing Configuration Items

bool XmlConfigHandler::deleteParameter(const QString &value, const QString &section, const QString &key)
{
    if(value.isEmpty() || section.isEmpty()) return false;
    
    if(key.isEmpty()) {
        int paramCount = m_configData[section].size();
        if(paramCount == 0) return false;
        
        auto paramIter = m_configData[section].begin();
        while(paramIter != m_configData[section].end()) {
            if(paramIter.value() == value) {
                paramIter = m_configData[section].erase(paramIter);
            } else {
                ++paramIter;
            }
        }
    } else {
        m_configData[section].remove(key);
    }
    
    saveConfiguration(m_configFilePath);
    return true;
}

This XML-based configuration system provides a flexible alternative to QSettings while maintaining similar functionality for application configuration management.

Tags: Qt QDomDocument XML configuration ini

Posted on Mon, 19 Oct 2026 16:04:24 +0000 by n1tr0b