XML 是可扩大标记语言(Extensible Markup Language)的缩写。XML 文件由内容和标记组成,通过以标记包围内容的方式将大部份内容包括在元素中。
Qt 中提供了多种读取XML文件的方法,这里简单的记录1下用 QDomDocument 读取的步骤。为何使用QDomDocument 呢,由于XML 本身就是1以树状结构组织数据的,而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 的的数据读入到1个树型列表控件中。下面是核心的代码:
#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⑻"?>
<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>
下面是软件界面: