XML 是可扩展标记语言(Extensible Markup Language)的缩写。XML 文件由内容和标记组成,通过以标记包围内容的方式将大部分内容包含在元素中。
Qt 中提供了多种读取XML文件的方法,这里简单的记录一下用 QDomDocument 读取的步骤。为什么使用QDomDocument 呢,因为XML 本身就是一以树状结构组织数据的,而DOM 也是将数据组织为树状结构,最适合直观地展示XML数据。
下面的代码是Qt 帮助文件中自带的例子代码:
- QDomDocument doc("mydocument");
- QFile file("mydocument.xml");
- if (!file.open(QIODevice::ReadOnly))
- return;
- if (!doc.setContent(&file))
- {
- file.close();
- return;
- }
- file.close();
- // print out the element names of all elements that are direct children
- // of the outermost element.
- QDomElement docElem = doc.documentElement();
- QDomNode n = docElem.firstChild();
- while (!n.isNull())
- {
- QDomElement e = n.toElement(); // try to convert the node to an element.
- if (!e.isNull())
- {
- cout << qPrintable(e.tagName()) << endl; // the node really is an element.
- }
- n = n.nextSibling();
- }
如果xml有多层,那么可以递归的去读取。我写了小程序将xml 的的数据读入到一个树型列表控件中。下面是核心的代码:
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QtXml>
- #include <QDialog>
- namespace Ui {
- class Dialog;
- }
- class QTreeWidgetItem;
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- void listDom(QDomElement& docElem, QTreeWidgetItem* pItem);
- void openXML(QString fileName);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- private slots:
- void openFile();
- };
- #endif // DIALOG_H
- #include "dialog.h"
- #include "ui_dialog.h"
- #include <QFileDialog>
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(openFile()));
- ui->treeWidget->setColumnCount(2);
- ui->treeWidget->setColumnWidth(0, 400);
- setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint);
- showMaximized();
- }
- void Dialog::openXML(QString fileName)
- {
- QFile file(fileName);
- if(file.open(QIODevice::ReadOnly))
- {
- QDomDocument dom("WCM");
- if (dom.setContent(&file))
- {
- ui->treeWidget->clear();
- QDomElement docElem = dom.documentElement();
- listDom(docElem, NULL);
- }
- }
- file.close();
- }
- void Dialog::openFile()
- {
- QString fileName = QFileDialog::getOpenFileName(this, tr("Open XML File"), "c:/", tr("XML Files (*.xml)"));
- if(!fileName.isEmpty())
- {
- openXML( fileName );
- }
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::listDom(QDomElement& docElem, QTreeWidgetItem * pItem)
- {
- QDomNode node = docElem.firstChild();
- if(node.toElement().isNull())
- {
- pItem->setText (1, docElem.text());
- }
- while(!node.isNull())
- {
- QDomElement element = node.toElement(); // try to convert the node to an element.
- if( !element.isNull() )
- {
- QTreeWidgetItem *item;
- if( pItem )
- {
- item = new QTreeWidgetItem(pItem);
- }
- else
- {
- item = new QTreeWidgetItem(ui->treeWidget);
- }
- item->setText(0, element.tagName());
- listDom(element, item);
- if( pItem )
- {
- pItem->addChild(item);
- }
- else
- {
- ui->treeWidget->addTopLevelItem(item);
- }
- }
- node = node.nextSibling();
- }
- return;
- }
下面是个测试 xml 文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <recipe type="dessert">
- <recipename cuisine="american" servings="1">Ice Cream Sundae</recipename>
- <ingredlist>
- <listitem>
- <quantity units="cups">0.5</quantity>
- <itemdescription>vanilla ice cream</itemdescription>
- </listitem>
- <listitem>
- <quantity units="tablespoons">3</quantity>
- <itemdescription>chocolate syrup or chocolate fudge</itemdescription>
- </listitem>
- <listitem>
- <quantity units="tablespoons">1</quantity>
- <itemdescription>nuts</itemdescription>
- </listitem>
- <listitem>
- <quantity units="each">1</quantity>
- <itemdescription>cherry</itemdescription>
- </listitem>
- </ingredlist>
- <utensils>
- <listitem>
- <quantity units="each">1</quantity>
- <utensilname>bowl</utensilname>
- </listitem>
- <listitem>
- <quantity units="each">1</quantity>
- <utensilname>spoons</utensilname>
- </listitem>
- <listitem>
- <quantity units="each">1</quantity>
- <utensilname>ice cream scoop</utensilname>
- </listitem>
- </utensils>
- <directions>
- <step>Using ice cream scoop, place vanilla ice cream into bowl.</step>
- <step>Drizzle chocolate syrup or chocolate fudge over the ice cream.</step>
- <step>Sprinkle nuts over the mound of chocolate and ice cream.</step>
- <step>Place cherry on top of mound with stem pointing upward.</step>
- <step>Serve.</step>
- </directions>
- <variations>
- <option>Replace nuts with raisins.</option>
- <option>Use chocolate ice cream instead of vanilla ice cream.</option>
- </variations>
- <preptime>5 minutes</preptime>
- </recipe>