Qt的Xml操作QDomDocument
Qt对于Xml的支持是很好的,一些我们需要的操作应有尽有,下面简单介绍一下怎样使用。主要有以下几点使用:
- 写xml到文件
- 读xml
- 添加节点到xml
- 删除xml中某节点信息
- 修改xml中某节点信息
准备工作
- .pro加入QT += xml
- 需要include QDomDocument QTextStream QFile三个头文件
WriteXml
直接上代码
void writeXml()
{QDomDocument doc;QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");QDomComment comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来"));QDomProcessingInstruction styleInstruction = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");doc.appendChild(xmlInstruction); // 开始文档(XML 声明)doc.appendChild(comment); // 注释doc.appendChild(styleInstruction); // 处理指令// 根元素 <Blogs>QDomElement root = doc.createElement("Books");root.setAttribute("Version", "1.0"); // 属性doc.appendChild(root);// 元素 <Blog>QDomElement child = doc.createElement("Book");root.appendChild(child);// 元素 <作者>、<时间>、<个人说明>QDomElement author = doc.createElement(QString::fromLocal8Bit("作者"));QDomElement home = doc.createElement(QString::fromLocal8Bit("时间"));QDomElement instruction = doc.createElement(QString::fromLocal8Bit("个人说明"));child.appendChild(author);child.appendChild(home);child.appendChild(instruction);// 元素的文本数据QDomText authorText = doc.createTextNode(QString::fromLocal8Bit("Vincent"));QDomText homeText = doc.createTextNode("2017年4月13日");QDomText instructionText = doc.createTextNode(QString::fromLocal8Bit("大宋枢密院常任委员会_委员"));author.appendChild(authorText);home.appendChild(homeText);instruction.appendChild(instructionText);// 保存 XML 文件QString strFile("Books.xml");QFile file(strFile);// 只写模式打开文件if (file.open(QFile::WriteOnly | QFile::Text)){QTextStream out(&file);doc.save(out, QDomNode::EncodingFromDocument);file.close();}
}
void writeXML()
{//打开或创建文件QString fileName{"test.xml"};QFile file(fileName);//QIODevice::Truncate表示清空原来的内容if(!file.open(QFile::WriteOnly|QFile::Truncate))return;//创建xml文档在内存中QDomDocument doc;//添加处理命令QDomProcessingInstruction instruction;instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");//创建注释QDomComment comment;comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来"));QDomProcessingInstruction styleInstruction;styleInstruction= doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");doc.appendChild(instruction); //文档开始声明doc.appendChild(comment);doc.appendChild(styleInstruction); // 处理指令//添加根节点QDomElement root=doc.createElement("library");root.setAttribute("Version","2.1");doc.appendChild(root);//添加第一个子节点及其子元素QDomElement book=doc.createElement("book");//方式一:创建属性 其中键值对的值可以是各种类型book.setAttribute("id",1);//方式二:创建属性 值必须是字符串QDomAttr time=doc.createAttribute("time");time.setValue("2013/6/13");book.setAttributeNode(time);QDomElement title=doc.createElement("title"); //创建子元素QDomText text; //设置括号标签中间的值text=doc.createTextNode("C++ primer");book.appendChild(title);title.appendChild(text);QDomElement author=doc.createElement("author"); //创建子元素text=doc.createTextNode("Stanley Lippman");author.appendChild(text);book.appendChild(author);//添加节点book做为根节点的子节点root.appendChild(book);//添加第二个子节点及其子元素book=doc.createElement("book");book.setAttribute("id",2);time=doc.createAttribute("time");time.setValue("2007/5/25");book.setAttributeNode(time);title=doc.createElement("title");text=doc.createTextNode("Thinking in Java");book.appendChild(title);title.appendChild(text);author=doc.createElement("author");text=doc.createTextNode("Bruce Eckel");author.appendChild(text);book.appendChild(author);root.appendChild(book);//输出到文件QTextStream out_stream(&file);doc.save(out_stream,4); //缩进4格file.close();
}
ReadXml
上代码
void readXML()
{//打开或创建文件QFile file("test.xml");if(!file.open(QFile::ReadOnly))return;QDomDocument doc;//设置wangfei1.xml到文档if(!doc.setContent(&file)){file.close();return;}file.close();//返回根节点QDomElement root=doc.documentElement();qDebug()<<root.nodeName();//如果xml根元素有属性(Version)将输出,Vinsion是用户自定义的属性,没有继续执行下一条命令if (root.hasAttribute("Version")) // 属性qDebug() << root.attribute("Version");/**********根元素之上(XML 声明、注释等)**********/QDomNode node = root.previousSibling();while (!node.isNull()){switch (node.nodeType()){case QDomNode::ProcessingInstructionNode :{QDomProcessingInstruction instruction = node.toProcessingInstruction();//输出处理指令,是用户自定义的,比如字符串“name”对应处理指令得到名字,这个命令是用户写的qDebug() << instruction.target() << instruction.data();if (QString::compare(instruction.target(), "xml") == 0) // 开始文档(XML 声明){//cout<<"处理命令xml"<<endl;// ...}else if (QString::compare(instruction.target(), "xml-stylesheet") == 0) // 处理指令{//cout<<"处理命令xml-stylesheet"<<endl;// ...}break;}case QDomNode::CommentNode :{QDomComment comment = node.toComment();qDebug() << comment.data();break;}default:break;}node = node.previousSibling();}//获得第一个子节点node=root.firstChild();while(!node.isNull()) //如果节点不空{if(node.isElement()) //如果节点是元素{//转换为元素QDomElement element=node.toElement();if (!element.isNull())// 节点的确是一个元素{//输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time");QDomNodeList list=element.childNodes();for(int i=0;i<list.count();++i){QDomNode n=list.at(i);//node = list.at(i);if(node.isElement()){qDebug()<<n.nodeName()<<":"<<n.toElement().text();element = n.toElement();//qDebug()<<element.nodeName()<<":"<<element.toElement().text();if (QString::compare(element.tagName(), QStringLiteral("作者")) == 0){// ...处理命令//cout<< "处理命令作者"<<endl;}else if (QString::compare(element.tagName(), QStringLiteral("时间")) == 0){//cout<<"处理命令时间"<<endl;// ...处理命令}else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == 0){//cout<<"处理命令个人说明"<<endl;// ...处理命令}}}}}//下一个兄弟节点node=node.nextSibling();}
}
AddXml
void addXML()
{//打开文件QFile file("test.xml");if(!file.open(QFile::ReadOnly))return;//增加一个一级子节点以及元素QDomDocument doc;if(!doc.setContent(&file)){file.close();return;}file.close();//创建根节点QDomElement root = doc.documentElement();//创建next子节点bookQDomElement book = doc.createElement("book");book.setAttribute("id",3);book.setAttribute("time","1813/1/27");QDomElement title = doc.createElement("title");QDomText text;text = doc.createTextNode("Pride and Prejudice");//添加text内容到title节点title.appendChild(text);//添加title到book节点book.appendChild(title);//添加book到根节点root.appendChild(book);if(!file.open(QFile::WriteOnly|QFile::Truncate))return;//输出到文件QTextStream out_stream(&file);doc.save(out_stream,4); //以缩进4格方式输出,也有其他输出方式(格式)file.close();
}
DeleteXml
void deleteXML()
{//打开文件QFile file("test.xml");if(!file.open(QFile::ReadOnly))return;//删除一个一级子节点及其元素,外层节点删除内层节点于此相同QDomDocument doc;if(!doc.setContent(&file)){file.close();return;}file.close();QDomElement root=doc.documentElement();//由标签名定位,本标签为book,以后可以是用string类型的字符串替换,实现动态QDomNodeList list=doc.elementsByTagName("book");//删除方式一,通过标签book后面的属性删除<book>到</book>for(int i=0;i<list.count();i++){//转化为元素QDomElement e=list.at(i).toElement();//找到time是2007/5/25这一条数据将其删除if(e.attribute("time")=="2007/5/25")root.removeChild(list.at(i));}//删除方式二,可以通过索引直接删除
// root.removeChild(list.at(1));if(!file.open(QFile::WriteOnly|QFile::Truncate))return;//输出到文件QTextStream out_stream(&file);doc.save(out_stream,4); //缩进4格file.close();
}
AmendXml
void amendXML()
{//打开文件QFile file("wangfei1.xml");if(!file.open(QFile::ReadOnly))return;//更新一个标签项,如果知道xml的结构,直接定位到那个标签上定点更新//或者用遍历的方法去匹配tagname或者attribut,value来更新QDomDocument doc;//设置wangfei.xml读到doc文档if(!doc.setContent(&file)){file.close();return;}file.close();/*** 知道xml结构,直接定位修改* 提取根节点**/QDomElement root=doc.documentElement();//以book标签存入list
// QDomNodeList list=root.elementsByTagName("book");
// QDomNode listNode=list.at(list.size()-2).firstChild();
// QDomNode oldnode=listNode.firstChild();
// //把title改成Emma
// listNode.firstChild().setNodeValue("aaaaaaa");
// QDomNode newnode=listNode.firstChild();
// listNode.replaceChild(newnode,oldnode);//使用遍历方法选择要修改的元素
// QDomNodeList lists =doc.childNodes();
// QDomNodeList list=root.elementsByTagName("book");QDomNode node = root.firstChild();//QDomNodeList list=root.elementsByTagName("book");while(!node.isNull()) //如果节点不空{if(node.isElement()) //如果节点是元素{//转换为元素QDomElement element=node.toElement();if (!element.isNull() && element.attribute("id") == "3")// 节点的确是一个元素{//输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空//qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time");QDomNodeList list=element.childNodes();for(int i=0;i<list.count();++i){QDomNode n=list.at(i);//node = list.at(i);if(node.isElement()){//qDebug()<<n.nodeName()<<":"<<n.toElement().text();element = n.toElement();//与上面qDebug效果相同//qDebug()<<element.nodeName()<<":"<<element.toElement().text();//这个if可以不需要,如果需要精确定位,以防数据相同所以要加这个嵌套ifif (QString::compare(element.tagName(), QStringLiteral("title")) == 0){if("Pride and Prejudice" == element.toElement().text()){// ...处理命令,在这个if里可以遍历想要的节点进行修改//新建一个旧的node缓存QDomNode oldNode = n.firstChild();n.firstChild().setNodeValue("changchun1");//新建一个新的newNode子节点QDomNode newNode = n.firstChild();//使用replaceChild替换noden.replaceChild(newNode,oldNode);}}else if (QString::compare(element.tagName(), QStringLiteral("时间")) == 0){//cout<<"处理命令时间"<<endl;// ...处理命令}else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == 0){//cout<<"处理命令个人说明"<<endl;// ...处理命令}}}}}//下一个兄弟节点node=node.nextSibling();}if(!file.open(QFile::WriteOnly|QFile::Truncate))return;//输出到文件QTextStream out_stream(&file);doc.save(out_stream,4); //缩进4格file.close();}