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
-
#include
-
-
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
-
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>