14.3. Запись в XML-документы.

Существует два основных подхода создания XML-файлов в приложениях Qt:

Выбор того или иного метода зачастую сильно зависит от используемого парсера -- SAX или DOM. Ниже приводится отрывок кода, который создает дерево DOM и записывает его в файл, с помощью 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); Вторым аргументом функции save() передается размер отступов. Ненулевое значение обеспечивает более удобочитаемый вид файла: <doc> <quote>Errare humanum est</quote> <translation>To err is human</translation> </doc> Другой вариант применим в приложениях, которые используют структуру DOM-дерева для внутренней организации данных. Такие приложения, как правило, читают XML-документы с помощью DOM-парсера в память, затем изменяют содержимое дерева и сохраняют изменения с помощью save() в XML-файл.

В примерах выше использовалась кодировка UTF-8, однако существует возможность сохранения данных в других кодировках. Для этого достаточно добавить в начало XML-файла соответствующую кодировку:

<?xml version="1.0" encoding="ISO-8859-1"?> Следующий отрывок кода показывает, как это можно сделать: QTextStream out(&file); QDomNode xmlNode = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"ISO-8859-1\""); doc.insertBefore(xmlNode, doc.firstChild()); doc.save(out, Indent); Создание XML-файлов вручную выполняется ничуть не сложнее. Для этого можно воспользоваться классом QTextStream и записать в него строки, как в обычный текстовый файл. Самое сложное в этом случае -- выполнить правильное экранирование служебных символов и значений атрибутов. Сделать это можно с помощью отдельной функции: QString escapeXml(const QString &str) { QString xml = str; xml.replace("&", "&amp;"); xml.replace("<", "&lt;"); xml.replace(">", "&gt;"); xml.replace(" ", "&apos;"); xml.replace("\"", "&quot;"); return xml; } Ниже приводится пример использования этой функции: QTextStream out(&file); out.setEncoding(QTextStream::UnicodeUTF8); out << "<doc>\n" << " <quote>" << escapeXml(quoteText) << "</quote>\n" << " <translation>" << escapeXml(translationText) << "</translation>\n" << "</doc>\n"; В ежеквартальнике Qt Quarterly вы найдете статью "Generating XML" (по адресу: http://doc.trolltech.com/qq/qq05-generating-xml.html, в которой приводится пример простого класса, создающего XML-файлы. Класс сам обслуживает экранирование служебных символов, вставляет отступы и задает кодировку символов, предоставляя нам возможность сконцентрироваться на содержимом XML-файла.