Reading and Writing XML Files with Qt's QDomDocument

XML (eXtensible Markup Language) is a platform-independent, text-based format designed to store and transmit structured data. It uses custom, human-readable tags to define content hierarchy, and supports attributes to add metadata to elements.

Example Scenario

We’ll implement XML read and write operations for a simple bookstore catalog using Qt’s QDomDocument class, which provides a DOM (Document Object Model) interface for creating, parsing, and modifying XML content.

Writing XML Content with QDomDocument

void BookManager::saveToXml()
{
    QFile outputFile("../book_catalog.xml");
    if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
    {
        qDebug() << "Failed to open file for writing";
        return;
    }

    QDomDocument xmlDoc;
    // Add XML declaration
    auto xmlDeclaration = xmlDoc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
    xmlDoc.appendChild(xmlDeclaration);

    // Create root element
    QDomElement rootElement = xmlDoc.createElement("bookstore");
    xmlDoc.appendChild(rootElement);

    // Create book element with category attribute
    QDomElement bookElement = xmlDoc.createElement("Book");
    bookElement.setAttribute("category", ui->categoryField->text());

    // Create title element with language attribute
    QDomElement titleElement = xmlDoc.createElement("Title");
    titleElement.setAttribute("lang", "en");
    titleElement.appendChild(xmlDoc.createTextNode(ui->titleField->text()));

    // Create other content elements
    QDomElement authorElement = xmlDoc.createElement("Author");
    authorElement.appendChild(xmlDoc.createTextNode(ui->authorField->text()));

    QDomElement pubDateElement = xmlDoc.createElement("Time");
    pubDateElement.appendChild(xmlDoc.createTextNode(ui->pubDateField->text()));

    QDomElement priceElement = xmlDoc.createElement("Price");
    priceElement.appendChild(xmlDoc.createTextNode(ui->priceField->text()));

    // Assemble book element hierarchy
    bookElement.appendChild(titleElement);
    bookElement.appendChild(authorElement);
    bookElement.appendChild(pubDateElement);
    bookElement.appendChild(priceElement);

    // Add book to root element
    rootElement.appendChild(bookElement);

    // Write formatted XML to file
    QTextStream writer(&outputFile);
    xmlDoc.save(writer, 4); // 4-space indentation for readability
    outputFile.close();
}

Reading XML Contant with QDomDocument

void BookManager::loadFromXml()
{
    QFile inputFile("../book_catalog.xml");
    if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file for reading";
        return;
    }

    QDomDocument xmlDoc;
    if (!xmlDoc.setContent(&inputFile))
    {
        inputFile.close();
        qDebug() << "Failed to parse XML content";
        return;
    }
    inputFile.close();

    QDomElement rootElement = xmlDoc.documentElement();
    if (rootElement.tagName() != "bookstore")
    {
        qDebug() << "Invalid XML root element";
        return;
    }

    QDomNode currentNode = rootElement.firstChild();
    while (!currentNode.isNull())
    {
        QDomElement bookElement = currentNode.toElement();
        if (!bookElement.isNull() && bookElement.tagName() == "Book")
        {
            // Populate category field from attribute
            ui->categoryField->setText(bookElement.attribute("category"));

            // Retrieve and populate title
            QDomElement titleElement = bookElement.firstChildElement("Title");
            if (!titleElement.isNull())
            {
                ui->titleField->setText(titleElement.text());
            }

            // Retrieve and populate author
            QDomElement authorElement = bookElement.firstChildElement("Author");
            if (!authorElement.isNull())
            {
                ui->authorField->setText(authorElement.text());
            }

            // Retrieve and populate publication date
            QDomElement pubDateElement = bookElement.firstChildElement("Time");
            if (!pubDateElement.isNull())
            {
                ui->pubDateField->setText(pubDateElement.text());
            }

            // Retrieve and populate price
            QDomElement priceElement = bookElement.firstChildElement("Price");
            if (!priceElement.isNull())
            {
                ui->priceField->setText(priceElement.text());
            }
        }
        currentNode = currentNode.nextSibling();
    }
}

Operation Results

When you trigger the save action (e.g., via a button click), the input data is serialized into an XML file with a structure like this:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <Book category="Fiction">
        <Title lang="en">The Great Gatsby</Title>
        <Author>F. Scott Fitzgerald</Author>
        <Time>1925</Time>
        <Price>12.99</Price>
    </Book>
</bookstore>

Triggering the load action reads the XML file content and populates all corresponding UI input fields with the stored data.

Tags: Qt framework QDomDocument XML Processing C++ File I/O

Posted on Thu, 05 Nov 2026 16:06:58 +0000 by rvpals