XML
,全称为
“
可扩展标记语言
”(extensible markup language).
是一种非常方便的
数据交换
与
数据存储
的工具。
我们在取得一个
XML
格式的文件后,需要作句法分析去提取发布方提供的信息。而
Qt
为
XML
提供了很好的支持,包括
DOM
方式的实现和
SAX
方式的实现。
二者主要区别是:
DOM (
Document Object Model
)
实现方式操作非常简单,但不适合处理过大文件;而
SAX
实现方式是能处理很大的
XML
文件,但是需要开发者写一些复杂的代码。
Qt
提供了对应于这两种用于 读取、操作和编写
XML
的实现类,分别是
QDomDocument
类和
QXmlStreamReader
类
,这里我们选
QDomDocument
类
来处理
XML
文件。
首先是读取
XML
主要操作包括:
1).
读取根节点:
QDomElement
root = doc.documentElement();
2).
读取第一个子节点:
QDomNode
node = root.firstChild();
3).
读取下一个子节点:
node = node.nextSibling();
4).
匹配结点标记:
node.toElement().tagName() == "note"
5).
读取节点文本:
no = childNode.toText().data();
QFile file(fileName);
if
(!file.open(QFile::ReadOnly | QFile::Text)) {
return
false
;
}
QString errorStr;
int
errorLine;
int
errorColumn;
QDomDocument doc;
if
(!doc.setContent(&file,
false
, &errorStr, &errorLine, &errorColumn))
{
// setContent
是将指定的内容指定给
QDomDocument
解析,第一参数可以是
QByteArray
或者是文件名等。
return
false
;
}
file.close();
可以通过
doc.childNodes()
获得
doc
的所有的 子节点 列表
QDomNodeList
。比如
QDomNodeList list=doc.childNodes();
for(int i=0;i<list.count();i++)
QDomNode
node=list.at(i);
// qDebug()<<”node name is “<<node.nodeName();
// qDebug()<<”node type is “<<
node
.nodeType();
通过上面的方法你就能知道
每个节点的 名字和类型
了,
节点名字就是 标记 的名字
。打印出来对照着
xml
文件看就很容易明白了。
QDomNode
类是一个父类
, QDomDocument
是
QDomNode
的一个子类
,鉴于大部分
QDomNode
的类型 都是
QDomDocument.
那么你可以使用
toDocument()
函数将
QDomNode
类型转换成
QDomDocument.
QString text=node.toElement().text();
上面的语句可以将一个
节点里的 文本 取出
,
也就是 标记内的文本 部分
。使用该函数获得的编码就已经是
unicode
格式了,不需要再做转换。
然后是写入
XML
创建节点,将其写入
XML
文件,主要操作包括:
1).
创建根节点:
QDomElement
root = doc.documentElement("rootName " );
2).
创建元素节点:
QDomElement
element = doc.createElement_x_x_x("nodeName");
3).
添加
元素节点
到
根节点:
root. a(element);
4).
创建文本节点:
QDomText
nodeText=doc.createTextNode("text");
5).
添加
文本节点
到
元素节点:
element. a(nodeText);
XML
文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<Notes>
<no>001</no>
<name>2010-05-10(13:53:24)</name>
<content>A meeting
!
</content>
<font>Script MT Bold</font>
</note>
</Notes>
QFile file(fileName);
if
(!file.open(QFile::ReadOnly | QFile::Text))
return
false
;
QString errorStr;
int
errorLine;
int
errorColumn;
QDomDocument doc;
if
(!doc.setContent(&file,
false
, &errorStr, &errorLine, &errorColumn))
return
false
;
file.close();
QDomElement root = doc.documentElement();
if
(root.tagName() !=
"root"
)
return
false
;
QDomElement element = doc.createElement_x_x_x(
"file"
);
QDomElement el_address = doc.createElement_x_x_x(
"address"
);
QDomText text_address = doc.createTextNode(
"text"
);
el_address.
a
(text_address);
element.
a
(el_address);
QDomElement el_path = doc.createElement_x_x_x_x(
"path"
);
QDomText text_path = doc.createTextNode(
"text"
);
el_path.
a
(text_path);
element.
a
(el_path);
root.
a
(element);
QFile f(fileName);
if
(!f.open(QFile::WriteOnly | QFile::Text))
return
false
;
QTextStream
out
(&f);
out.setCodec("UTF-8"); //
中文编码
//
doc.save(out,4,QDomNode::EncodingFromTextStream);
doc.save(out, 3);
f.close();
这里
所有需要
append
的字节点只能由
QDomDocument
对象
create
,而
不能直接
new
它
,否则永远也看不到新添加的节点,另外,
读取和写入的文件流必须创建两个
,否则会将需要写入的文档继续在原来文档的后面,造成多个根节点。