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.