用 Qt 中的 QDomDocument类 处理 XML 文件(下)
QDomDocument doc;
1).创建根节点:QDomElement root = doc.documentElement("rootName " );
2).创建元素节点:QDomElement element = doc.createElement_x("nodeName");
3).添加元素节点到根节点:root. appendChild(element);
4).创建元素文本:QDomText nodeText=doc.createTextNode("text");
5).添加元素文本到元素节点:element. appendChild(nodeText);
在本项目中,假设便签的属性有序号、名字、内容、字体、字号、颜色、粗细、斜体、下划线这几项,则在文件中添加一个便签节点的操作如下:
QDomDocument doc;
instruction = doc.createProcessingInstruction("xml","version="1.0" encoding="UTF-8"");
doc.appendChild(instruction);
QDomElement root = doc.createElement_x("Notes");
doc.appendChild(root);
QDomElement note = doc.createElement_x("note");
root.appendChild(note);
QDomElement no = doc.createElement_x("no");
note.appendChild(no);
...
...
QDomText no_text = doc.createTextNode("001");
...
...
则得到一个便签节点,将其保存到test.xml文件中,代码如下:
QFile file("test.xml");
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate |QIODevice::Text))
return ;
QTextStream out(&file);
out.setCodec("UTF-8");
doc.save(out,4,QDomNode::EncodingFromTextStream);
file.close();
则test.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Notes>
<note>
<no>001</no>
<name>2010-05-10(13:53:24)</name>
<content>A meeting!</content>
<font>Script MT Bold</font>
<fontSize>16</fontSize>
<color> #00ffff</color>
<weight>0</weight>
<fontItalic>true</fontItalic>
<fontUnderline>true</fontUnderline>
</note>
</Notes>
上面是创建一个便签节点,若要继续添加便签节点,则需要在已有节点后增加一个新节点,并重写入XML文件。
2. 加载、查找便签时要读取XML文档中的节点信息,DOM实现方式是将整个文档当作一个对象来装入内存进行处理,然后开发者可以访问这个对象中的每一个节点,每一个节点对应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();
//========================遍历节点================
可以通过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 “<<.nodeType();
}
//==============================================
以下是项目中读取便签属性的函数实现代码:
void MainWindow::parseAttr(const QDomElement &element)
{
QString no,name,content,font,fontSize,color;
QDomNode node = element.firstChild();
while (!node.isNull()) {
if (node.toElement().tagName() == "note") {//匹配note节点
parseAttr(node.toElement());
} else if (node.toElement().tagName() == "no") {//匹配属性no
QDomNode childNode = node.firstChild();
if (childNode.nodeType() == QDomNode::TextNode) {
no = childNode.toText().data();
}
}
else if (node.toElement().tagName() == "name") //匹配属性name
...
...
node = node.nextSibling();//读取兄弟节点
}
}
3. 删除便签时,要删除相应的XML节点,用到的主要函数为:root.removeChild(node); 但在删除某个节点后要重写整个文件。
以上对XML文件的重写操作是必须的,因此在文件的打开方式中要加上QIODevice::Truncate,表示覆盖重写。目前还没有找到可以直接修改文件的方法,但若文件很大的情况下,必须考虑相
应的效率问题。
由于本项目在启动时需要将所有便签加载到内存,因此选用DOM方式比较合适,但如果处理的XML文件很大,而且不需要全部读到内存时,可以用SAX实现方式,它按阶段将文档读取到内存中,
在碰到标签或者其它阶段的时候,可以调用开发者预先设计好的回调函数去处理,这样效率比DOM方式更高。
4.读取XML文件内容:
//===================打开document===============add me ======
QString xmlPath = "filename.xml";
QFile file(xmlPath);
if (!file.open(QFile::ReadOnly | QFile::Text))
return ;
QString errorStr;
int errorLine;
int errorColumn;
QDomDocument doc;
if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))
return ;
file.close();
//也可以用doc.setContent(&file)带一个参数就行。
//=============================================================
然后按照上面方式遍历数据,修改后在以上面相同的方式写入到XML文件中。
//=========================================附加一段代码 创建XML文件===============
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QString xmlPath = "InitInfo.xml";
QFile file(xmlPath);
if (!file.open(QFile::ReadOnly | QFile::Text))
return 1;
QString errorStr;
int errorLine;
int errorColumn;
QDomDocument doc;
if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))
return 1;
file.close();
QDomElement root = doc.documentElement();
QString str = root.tagName();
if (root.tagName() != "Root")
return 1;
QDomElement element = doc.createElement_x("device3");
element.setAttribute("ChildName","Content");
QDomElement el_address = doc.createElement_x("Content ");
el_address.setAttribute("key","equipmentname");
el_address.setAttribute("value","CSC101B");
el_address.setAttribute("name","装置名称");
//QDomText text_address = doc.createTextNode("key");
//el_address.appendChild(text_address);
element.appendChild(el_address);
QDomElement el_path = doc.createElement_x("path");
QDomText text_path = doc.createTextNode("aa");
el_path.appendChild(text_path);
element.appendChild(el_path);
root.appendChild(element);
QFile f(xmlPath);
if (!f.open(QFile::WriteOnly | QFile::Text))
return 1;
QTextStream out(&f);
QTextCodec * codec = QTextCodec::codecForName("GBK");
out.setCodec(codec);
QDomDocument xmlDoc;
QString strHead("version="1.0" encoding="GB2312"");
xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", strHead));
out<<xmlDoc.toString();
root.save(out, 3);
f.close();
return 0;
}
用 Qt 中的 QDomDocument类 处理 XML 文件(下)的更多相关文章
- 用 Qt 中的 QDomDocument类 处理 XML 文件(上)
我们可以看到,如果所要读取的XML文件不是很大,采用DOM读取方法还是很便捷的,由于我用的也是DOM树读取的方法,所以,本文所介绍的也主要是基于DOM的方法读取. 根据常用的操作,我简单的把对XM ...
- 用 Qt 中的 QDomDocument类 处理 XML 文件
XML,全称为 “可扩展标记语言”(extensible markup language).是一种非常方便的数据交换与数据存储的工具. 我们在取得一个XML格式的文件后,需要作句法分析去提取发布方提供 ...
- Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:
Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...
- Qt 中一些常用类中文说明
Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进 ...
- 第11课 Qt中的字符串类
1. 历史遗留问题和解决方案 (1)历史遗留问题 ①C语言不支持真正意义上的字符串 ②C语言用字符数组和一组函数实现字符串操作 ③C语言不支持自定义类型,因此无法获得字符串类型 (2)解决方案 ①从C ...
- Android中通过代码获取arrays.xml文件中的数据
android工程res/valuse文件夹下的arrays.xml文件中用于放各种数组数据,比如字符串数组.整型数组等,数组中的数据可能是具体的值,也有可能是对资源数据的引用,下面针对这两种情况通过 ...
- 用java语言将数据库中的数据表转换为xml文件的通用程序(细化)
转自:https://www.cnblogs.com/wudage/p/7650685.html 总是在网络上copy别人的源代码,今天我也贴出自己今天写的源码,相信这个程序会对大家在平时的工作中需要 ...
- JAXB—Java类与XML文件之间转换
JAXB-Java类与XML文件之间转换 简介 JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生 ...
- C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?
C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...
随机推荐
- Day17 表单验证、滚动菜单、WEB框架
一.表单验证的两种实现方式 1.DOM绑定 <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- Python深入学习笔记(二)
计数器Counter Counter类是自Python2.7起增加的,属于字典类的子类,是一个容器对象,主要用来统计散列对象,支持集合操作+.-.&.|,其中后两项分别返回两个Counter对 ...
- init_sequence所对应的函数
一.init_sequence内容 init_fnc_t *init_sequence[] = { cpu_init, /* basic cpu dependent setup */ board_in ...
- Ubuntu14.04 和 Windows7 双系统安装
用了一个暑假,我原来的Ubuntu终于挂了,连gnome桌面器都进不去了,索性重装整个Ubuntu.至少这次我知道什么都升级是一个很糟糕的行为. 由于笔者的电脑原来是Win8预装机,所以各种地方都是的 ...
- java数组遍历——iterator和for方法
import Java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayTest ...
- Oracle 字符集的查看和修改 -转
一.什么是Oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系.ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据.它使数据库 ...
- [LeetCode#252] Meeting Rooms
Problem: Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2] ...
- 【转】MFC下拉列表框的用法
原文网址:http://blog.csdn.net/kinglimy/article/details/6452239 Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是 ...
- 【转】压缩Virtualbox的vdi文件
原文网址:http://i.rexdf.org/blog/2014/10/06/ya-suo-virtualboxde-vdiwen-jian/ 问题实际上比较简单,我在Arch Linux杂记中给出 ...
- C#编程技术层次
不谈具体领域(比如搜索,视频,网络等),单就编程语言这个垂直方向,大体上对它有一个如下的层次划分. 1. 基本运用C#语法,在各种工具和示例代码的支持下,完成一些基本程序任务 2. 熟练掌握面向对象与 ...