Writing XML
There are basically two approaches for generating XML files from Qt applications:
- We can build a DOM tree and call save() on it.
- We can generate XML by hand.
The choice between these approaches is often independent of whether we use SAX or DOM for reading XML documents.
Here's a code snippet that illustrates how we can create a DOM tree and write it using a QTextStream:
const int Indent = 4; QDomDocument doc; QDomElement root = doc.createElement("doc"); QDomElement quote = doc.createElement("quote"); QDomElement translation = doc.createElement("translation"); QDomText quoteText = doc.createTextNode("Errare humanum est"); QDomText translationText = doc.createTextNode("To err is human"); doc.appendChild(root); root.appendChild(quote); root.appendChild(translation); quote.appendChild(quoteText); translation.appendChild(translationText); QTextStream out(&file); doc.save(out, Indent);
The second argument to save() is the indentation size to use. A non-zero value makes the file easier for humans to read. Here's the XML file output:
Errare humanum est To err is human
Another scenario occurs in applications that use the DOM tree as their primary data structure. These applications would normally read in XML documents using DOM, then modify the DOM tree in memory, and finally call save() to convert the tree back to XML.
In the example above, we used UTF-8 as the encoding. We can use another encoding by prepending
to the DOM tree. The following code snippet shows how to do this:
QTextStream out(&file); QDomNode xmlNode = doc.createProcessingInstruction("xml", "version="1.0" encoding="ISO-8859-1""); doc.insertBefore(xmlNode, doc.firstChild()); doc.save(out, Indent);
Generating XML files by hand isn't much harder than using DOM. We can use QTextStream and write the strings as we would do with any text file. The most tricky part is to escape special characters in text and attribute values. We can do this in a separate function:
QString escapeXml(const QString &str) { QString xml = str; xml.replace("&", "&"); xml.replace("<", "<"); xml.replace(">", ">"); xml.replace("'", "'"); xml.replace(""", """); return xml; }
Here's an example that makes use of it:
QTextStream out(&file); out.setEncoding(QTextStream::UnicodeUTF8); out << " " << " " << escapeXml(quoteText) << " " << " " << escapeXml(translationText) << " " << " "
The Qt Quarterly article "Generating XML", available online at http://doc. trolltech.com/qq/qq05-generating-xml.html, presents a very simple class that makes it easy to generate XML files. The class takes care of the details such as special characters, indentation, and encoding issues, leaving us free to concentrate on the XML we want to generate.