Qt的Xml操作QDomDocument
Posted mtn007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt的Xml操作QDomDocument相关的知识,希望对你有一定的参考价值。
Qt对于Xml的支持是很好的,一些我们需要的操作应有尽有,下面简单介绍一下怎样使用。主要有以下几点使用:
- 写xml到文件
- 读xml
- 添加节点到xml
- 删除xml中某节点信息
- 修改xml中某节点信息
准备工作
- .pro加入QT += xml
- 需要include QDomDocument QTextStream QFile三个头文件
直接上代码
WriteXml
1 void writeXml() 2 { 3 QDomDocument doc; 4 QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version="1.0" encoding="UTF-8" standalone="yes""); 5 QDomComment comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来")); 6 QDomProcessingInstruction styleInstruction = doc.createProcessingInstruction("xml-stylesheet", "type="text/css" href="style.css""); 7 doc.appendChild(xmlInstruction); // 开始文档(XML 声明) 8 doc.appendChild(comment); // 注释 9 doc.appendChild(styleInstruction); // 处理指令 10 // 根元素 <Blogs> 11 QDomElement root = doc.createElement("Books"); 12 root.setAttribute("Version", "1.0"); // 属性 13 doc.appendChild(root); 14 15 // 元素 <Blog> 16 QDomElement child = doc.createElement("Book"); 17 root.appendChild(child); 18 19 // 元素 <作者>、<时间>、<个人说明> 20 QDomElement author = doc.createElement(QString::fromLocal8Bit("作者")); 21 QDomElement home = doc.createElement(QString::fromLocal8Bit("时间")); 22 QDomElement instruction = doc.createElement(QString::fromLocal8Bit("个人说明")); 23 child.appendChild(author); 24 child.appendChild(home); 25 child.appendChild(instruction); 26 27 // 元素的文本数据 28 QDomText authorText = doc.createTextNode(QString::fromLocal8Bit("Vincent")); 29 QDomText homeText = doc.createTextNode("2017年4月13日"); 30 QDomText instructionText = doc.createTextNode(QString::fromLocal8Bit("大宋枢密院常任委员会_委员")); 31 author.appendChild(authorText); 32 home.appendChild(homeText); 33 instruction.appendChild(instructionText); 34 35 // 保存 XML 文件 36 QString strFile("Books.xml"); 37 QFile file(strFile); 38 // 只写模式打开文件 39 if (file.open(QFile::WriteOnly | QFile::Text)) 40 { 41 QTextStream out(&file); 42 doc.save(out, QDomNode::EncodingFromDocument); 43 file.close(); 44 } 45 } 46 void writeXML() 47 { 48 //打开或创建文件 49 QString fileName{"test.xml"}; 50 QFile file(fileName); 51 //QIODevice::Truncate表示清空原来的内容 52 if(!file.open(QFile::WriteOnly|QFile::Truncate)) 53 return; 54 55 //创建xml文档在内存中 56 QDomDocument doc; 57 //添加处理命令 58 QDomProcessingInstruction instruction; 59 instruction = doc.createProcessingInstruction("xml", "version="1.0" encoding="UTF-8""); 60 //创建注释 61 QDomComment comment; 62 comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来")); 63 QDomProcessingInstruction styleInstruction; 64 styleInstruction= doc.createProcessingInstruction("xml-stylesheet", "type="text/css" href="style.css""); 65 doc.appendChild(instruction); //文档开始声明 66 doc.appendChild(comment); 67 doc.appendChild(styleInstruction); // 处理指令 68 69 70 //添加根节点 71 QDomElement root=doc.createElement("library"); 72 root.setAttribute("Version","2.1"); 73 doc.appendChild(root); 74 //添加第一个子节点及其子元素 75 QDomElement book=doc.createElement("book"); 76 //方式一:创建属性 其中键值对的值可以是各种类型 77 book.setAttribute("id",1); 78 //方式二:创建属性 值必须是字符串 79 QDomAttr time=doc.createAttribute("time"); 80 time.setValue("2013/6/13"); 81 book.setAttributeNode(time); 82 QDomElement title=doc.createElement("title"); //创建子元素 83 QDomText text; //设置括号标签中间的值 84 text=doc.createTextNode("C++ primer"); 85 book.appendChild(title); 86 title.appendChild(text); 87 QDomElement author=doc.createElement("author"); //创建子元素 88 text=doc.createTextNode("Stanley Lippman"); 89 author.appendChild(text); 90 book.appendChild(author); 91 //添加节点book做为根节点的子节点 92 root.appendChild(book); 93 94 //添加第二个子节点及其子元素 95 book=doc.createElement("book"); 96 book.setAttribute("id",2); 97 time=doc.createAttribute("time"); 98 time.setValue("2007/5/25"); 99 book.setAttributeNode(time); 100 title=doc.createElement("title"); 101 text=doc.createTextNode("Thinking in Java"); 102 book.appendChild(title); 103 title.appendChild(text); 104 105 author=doc.createElement("author"); 106 text=doc.createTextNode("Bruce Eckel"); 107 author.appendChild(text); 108 book.appendChild(author); 109 root.appendChild(book); 110 111 //输出到文件 112 QTextStream out_stream(&file); 113 doc.save(out_stream,4); //缩进4格 114 file.close(); 115 }
ReadXml
1 void readXML() 2 { 3 //打开或创建文件 4 QFile file("test.xml"); 5 if(!file.open(QFile::ReadOnly)) 6 return; 7 8 QDomDocument doc; 9 //设置wangfei1.xml到文档 10 if(!doc.setContent(&file)) 11 { 12 file.close(); 13 return; 14 } 15 16 file.close(); 17 18 //返回根节点 19 QDomElement root=doc.documentElement(); 20 qDebug()<<root.nodeName(); 21 //如果xml根元素有属性(Version)将输出,Vinsion是用户自定义的属性,没有继续执行下一条命令 22 if (root.hasAttribute("Version")) // 属性 23 qDebug() << root.attribute("Version"); 24 /**********根元素之上(XML 声明、注释等)**********/ 25 QDomNode node = root.previousSibling(); 26 while (!node.isNull()) 27 { 28 switch (node.nodeType()) 29 { 30 case QDomNode::ProcessingInstructionNode : 31 { 32 QDomProcessingInstruction instruction = node.toProcessingInstruction(); 33 //输出处理指令,是用户自定义的,比如字符串“name”对应处理指令得到名字,这个命令是用户写的 34 qDebug() << instruction.target() << instruction.data(); 35 if (QString::compare(instruction.target(), "xml") == 0) // 开始文档(XML 声明) 36 { 37 //cout<<"处理命令xml"<<endl; 38 // ... 39 } 40 else if (QString::compare(instruction.target(), "xml-stylesheet") == 0) // 处理指令 41 { 42 //cout<<"处理命令xml-stylesheet"<<endl; 43 // ... 44 } 45 break; 46 } 47 case QDomNode::CommentNode : 48 { 49 QDomComment comment = node.toComment(); 50 qDebug() << comment.data(); 51 break; 52 } 53 default: 54 break; 55 } 56 node = node.previousSibling(); 57 } 58 59 //获得第一个子节点 60 node=root.firstChild(); 61 while(!node.isNull()) //如果节点不空 62 { 63 if(node.isElement()) //如果节点是元素 64 { 65 //转换为元素 66 QDomElement element=node.toElement(); 67 if (!element.isNull())// 节点的确是一个元素 68 { 69 //输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空 70 qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time"); 71 QDomNodeList list=element.childNodes(); 72 for(int i=0;i<list.count();++i) 73 { 74 QDomNode n=list.at(i); 75 //node = list.at(i); 76 if(node.isElement()) 77 { 78 qDebug()<<n.nodeName()<<":"<<n.toElement().text(); 79 element = n.toElement(); 80 //qDebug()<<element.nodeName()<<":"<<element.toElement().text(); 81 if (QString::compare(element.tagName(), QStringLiteral("作者")) == 0) 82 { 83 // ...处理命令 84 //cout<< "处理命令作者"<<endl; 85 } 86 else if (QString::compare(element.tagName(), QStringLiteral("时间")) == 0) 87 { 88 //cout<<"处理命令时间"<<endl; 89 // ...处理命令 90 } 91 else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == 0) 92 { 93 //cout<<"处理命令个人说明"<<endl; 94 // ...处理命令 95 } 96 } 97 98 } 99 } 100 } 101 //下一个兄弟节点 102 node=node.nextSibling(); 103 } 104 }
AddXml
1 void addXML() 2 { 3 //打开文件 4 QFile file("test.xml"); 5 if(!file.open(QFile::ReadOnly)) 6 return; 7 //增加一个一级子节点以及元素 8 QDomDocument doc; 9 if(!doc.setContent(&file)) 10 { 11 file.close(); 12 return; 13 } 14 file.close(); 15 //创建根节点 16 QDomElement root = doc.documentElement(); 17 //创建next子节点book 18 QDomElement book = doc.createElement("book"); 19 book.setAttribute("id",3); 20 book.setAttribute("time","1813/1/27"); 21 QDomElement title = doc.createElement("title"); 22 QDomText text; 23 text = doc.createTextNode("Pride and Prejudice"); 24 //添加text内容到title节点 25 title.appendChild(text); 26 //添加title到book节点 27 book.appendChild(title); 28 //添加book到根节点 29 root.appendChild(book); 30 31 if(!file.open(QFile::WriteOnly|QFile::Truncate)) 32 return; 33 //输出到文件 34 QTextStream out_stream(&file); 35 doc.save(out_stream,4); //以缩进4格方式输出,也有其他输出方式(格式) 36 file.close(); 37 }
DeleteXml
1 void deleteXML() 2 { 3 //打开文件 4 QFile file("test.xml"); 5 if(!file.open(QFile::ReadOnly)) 6 return; 7 8 //删除一个一级子节点及其元素,外层节点删除内层节点于此相同 9 QDomDocument doc; 10 if(!doc.setContent(&file)) 11 { 12 file.close(); 13 return; 14 } 15 file.close(); 16 17 QDomElement root=doc.documentElement(); 18 //由标签名定位,本标签为book,以后可以是用string类型的字符串替换,实现动态 19 QDomNodeList list=doc.elementsByTagName("book"); 20 21 //删除方式一,通过标签book后面的属性删除<book>到</book> 22 for(int i=0;i<list.count();i++) 23 { 24 //转化为元素 25 QDomElement e=list.at(i).toElement(); 26 //找到time是2007/5/25这一条数据将其删除 27 if(e.attribute("time")=="2007/5/25") 28 root.removeChild(list.at(i)); 29 } 30 //删除方式二,可以通过索引直接删除 31 // root.removeChild(list.at(1)); 32 33 if(!file.open(QFile::WriteOnly|QFile::Truncate)) 34 return; 35 //输出到文件 36 QTextStream out_stream(&file); 37 doc.save(out_stream,4); //缩进4格 38 file.close(); 39 }
AmendXml
1 void amendXML() 2 { 3 //打开文件 4 QFile file("wangfei1.xml"); 5 if(!file.open(QFile::ReadOnly)) 6 return; 7 8 //更新一个标签项,如果知道xml的结构,直接定位到那个标签上定点更新 9 //或者用遍历的方法去匹配tagname或者attribut,value来更新 10 QDomDocument doc; 11 //设置wangfei.xml读到doc文档 12 if(!doc.setContent(&file)) 13 { 14 file.close(); 15 return; 16 } 17 file.close(); 18 19 /** 20 * 知道xml结构,直接定位修改 21 * 提取根节点 22 * 23 */ 24 QDomElement root=doc.documentElement(); 25 //以book标签存入list 26 // QDomNodeList list=root.elementsByTagName("book"); 27 // QDomNode listNode=list.at(list.size()-2).firstChild(); 28 // QDomNode oldnode=listNode.firstChild(); 29 // //把title改成Emma 30 // listNode.firstChild().setNodeValue("aaaaaaa"); 31 // QDomNode newnode=listNode.firstChild(); 32 // listNode.replaceChild(newnode,oldnode); 33 34 35 //使用遍历方法选择要修改的元素 36 // QDomNodeList lists =doc.childNodes(); 37 // QDomNodeList list=root.elementsByTagName("book"); 38 39 QDomNode node = root.firstChild(); 40 41 //QDomNodeList list=root.elementsByTagName("book"); 42 43 while(!node.isNull()) //如果节点不空 44 { 45 if(node.isElement()) //如果节点是元素 46 { 47 //转换为元素 48 QDomElement element=node.toElement(); 49 if (!element.isNull() && element.attribute("id") == "3")// 节点的确是一个元素 50 { 51 //输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空 52 //qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time"); 53 QDomNodeList list=element.childNodes(); 54 for(int i=0;i<list.count();++i) 55 { 56 QDomNode n=list.at(i); 57 //node = list.at(i); 58 if(node.isElement()) 59 { 60 //qDebug()<<n.nodeName()<<":"<<n.toElement().text(); 61 element = n.toElement(); 62 //与上面qDebug效果相同 63 //qDebug()<<element.nodeName()<<":"<<element.toElement().text(); 64 65 66 //这个if可以不需要,如果需要精确定位,以防数据相同所以要加这个嵌套if 67 if (QString::compare(element.tagName(), QStringLiteral("title")) == 0) 68 { 69 70 if("Pride and Prejudice" == element.toElement().text()) 71 { 72 // ...处理命令,在这个if里可以遍历想要的节点进行修改 73 //新建一个旧的node缓存 74 QDomNode oldNode = n.firstChild(); 75 n.firstChild().setNodeValue("changchun1"); 76 //新建一个新的newNode子节点 77 QDomNode newNode = n.firstChild(); 78 //使用replaceChild替换node 79 n.replaceChild(newNode,oldNode); 80 } 81 82 } 83 84 else if (QString::compare(element.tagName(), QStringLiteral("时间")) == 0) 85 { 86 //cout<<"处理命令时间"<<endl; 87 // ...处理命令 88 } 89 else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == 0) 90 { 91 //cout<<"处理命令个人说明"<<endl; 92 // ...处理命令 93 } 94 } 95 96 } 97 } 98 } 99 //下一个兄弟节点 100 node=node.nextSibling(); 101 } 102 103 104 if(!file.open(QFile::WriteOnly|QFile::Truncate)) 105 return; 106 //输出到文件 107 QTextStream out_stream(&file); 108 doc.save(out_stream,4); //缩进4格 109 file.close(); 110 111 }
以上是关于Qt的Xml操作QDomDocument的主要内容,如果未能解决你的问题,请参考以下文章
Qt读写三种文件,QSettings读ini配置文件,QJsonDocument读JSON文件,QDomDocument读xml文件
关于Qt 报QDomDocument: No such file or directory错误解决办法