Qt中xml的读写
我们可以看到,如果所要读取的XML文件不是很大,采用DOM读取方法还是很便捷的,由于我用的也是DOM树读取的方法,所以,本文所介绍的也主要是基于DOM的方法读取。 根据常用的操作,我简单的把对XML的操作分为以下几类: 1 首先对XML文件进行操作,打开文件。 这个其实就是对文件进行操作,可以把它直接定义为构造函数,在对对象进行初始化时完成。 TopoDataReader::TopoDataReader(const wstring &filePath):_filePath(filePath),_qDomDoc("mydocument"),_qFile(QString::fromStdWString(filePath)) 2 读取XML文件中的节点内容 假设XML文件格式如下 (1) <switchs> <switch snmpip=211.87.235.136 newwork=front> </switch> </switchs> (2) <ip>211.87.235.136</ip> 对于第一种情况,采用如下方法: QDomElement docElem = _qDomDoc.documentElement(); QDomNode nodeswitch=docElem.elementsByTagName("switch ");//红色的为标签名 QDomElement elemnodeswitch=nodeswitch.toElement(); string snmpip=qPrintable(elemnodeswitch.attribute("snmpip"));//network的也是如此方法获取 对于第二种情况,采用如下方法: 直接调用text() API就可以了 string ip=qPrintable(elementnodeip.text()); 但是,假设文件中有多个同样的节点,如下 <a> <b></b> </a> 这样用elementsByTagName("b")返回的就是一个childNodes()而不是一个单独的node了。 我们可以使用at()方法具体定位。 另外,我们还可以使用这样一种方法获取节点的值,假设XML文件如下 - +<switch snmpIp="192.168.120.251" network="front"> 比如说,上面的那个ip节点就是nodeswitch.childNodes().at(3)。 这样做得好处就是不用担心重复的问题,只要你确定switch节点确定对了,底下的也就一定能确定了。 3 返回某个节点下子节点的个数 这个简单,也是直接调API QDomElement docElem = _qDomDoc.documentElement(); 好了,临时想起来就这么多。以后想起来再添。 //============================================================================================================================ Qt学习之XML读写操作小结 Qt学习之XML读写操作小结 这几天搜集qt对XML格式文件的读写,着重于DOM这种方式,先将搜集的资料粘贴在下面, 以一个完整的流程: 一些复杂的代码。Qt提供了对应于这两种用于读取、操作和编写XML的实现类,分别是QDomDocument类和QXmlStreamReader类,由于在项目中涉及的文件不大,因此我们选用QDomDocument类来 处理。 项目中涉及便签的增删改查,对应于XML文件中相应标记的读、写和修改,下面分别介绍: 1).创建根节点:QDomElement root = doc.documentElement("rootName " ); 2).创建元素节点:QDomElement element = doc.createElement_x_x("nodeName"); 3).添加元素节点到根节点:root. appendChild(element); 4).创建元素文本:QDomText nodeText=doc.createTextNode("text"); 5).添加元素文本到元素节点:element. appendChild(nodeText); 在本项目中,假设便签的属性有序号、名字、内容、字体、字号、颜色、粗细、斜体、下划线这几项,则在文件中添加一个便签节点的操作如下: QDomDocument doc; instruction = doc.createProcessingInstruct doc.appendChild(instruction); QDomElement root = doc.createElement_x_x("Notes"); doc.appendChild(root); QDomElement note = doc.createElement_x_x("note"); root.appendChild(note); QDomElement no = doc.createElement_x_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(); 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方式更高。 然后按照上面方式遍历数据,修改后在以上面相同的方式写入到XML文件中。 return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |