项目的pro文件里面添加:
QT +=core xml
在路径C:\Users\Administrator\Desktop\ZGXIPCDemo中存放device.xml文件。内容以及各式如下:
使用qDebug()显示读取文件的内容
#include
#include
#include
#include
void query_dev_xml(QString dev_xml_dir); //查询xml,dev_xml_dir是xml文件的存放地址
//查询制定的.xml中相应信息,显示在终端
//dev_xml_dir .xml文件的存放地址
void devmanager::query_dev_xml(QString dev_xml_dir) //查询xml
{
QFile file(dev_xml_dir);//
if(!file.open(QFile::ReadOnly|QFile::Text))
{
qDebug()<<"cannot open file";
}
else {
qDebug()<<"file opened!";
}
QXmlStreamReader reader;
reader.setDevice(&file);
while(!reader.atEnd())
{
QXmlStreamReader::TokenType type =reader.readNext();
//根据记号的类型进行输出
if (type==QXmlStreamReader::StartElement)
{
qDebug()<<"start element:"<<reader.name()<<"reader.text:"<<reader.text();
if(reader.attributes().hasAttribute("id"))
{
qDebug()<<"has attribute device id="<<reader.attributes().value("id");
qDebug()<<"version"<<reader.attributes().value("version");
qDebug()<<"password: "<<reader.attributes().value("password");
qDebug()<<"username: "<<reader.attributes().value("username");
qDebug()<<"channelno: "<<reader.attributes().value("channelno");
qDebug()<<"port: "<<reader.attributes().value("port");
qDebug()<<"ip: "<<reader.attributes().value("ip");
qDebug()<<"type: "<<reader.attributes().value("type");
qDebug()<<"name: "<<reader.attributes().value("name");
qDebug()<<"id: "<<reader.attributes().value("id");
}
else
{
qDebug()<<"element has no id";
}
}
if(type==QXmlStreamReader::EndElement)
qDebug()<<" end element: "<<reader.name();
if (type==QXmlStreamReader::Characters&&!reader.isWhitespace())
qDebug()<<"Characters and is whitespace: "<<reader.text();
}
file.close();
}
1、直接填写具体信息
void write_dev_xml(QString dev_xml_dir); //写入xml数据,其它设置同上
//将设备信息写入.xml文件中
//dev_xml_dir:.xml文件地址 devinfo:设备信息
void devmanager::write_dev_xml(QString dev_xml_dir)//, dev_info devinfo
{
QFile file(dev_xml_dir);//
if(!file.open(QFile::WriteOnly|QFile::Text|QFile::Truncate))
{
qDebug()<<"cannot open file to write";
}
else
{
qDebug()<<"write file opened!";
}
QXmlStreamWriter writer;
// QXmlStreamReader reader; //
QXmlStreamAttributes attributes; //QXmlStreamAttributes,而非QXmlStreamAttribute
writer.setCodec("UTF-8");
writer.setDevice(&file);
writer.setAutoFormatting(true);//自动格式
//attributes.clear();
writer.writeStartDocument();
writer.writeStartElement("root");
writer.writeStartElement("device");
attributes.append("version"," "); //由""修改为" ",否则生成文件内容空白
attributes.append("password","admin508");
attributes.append("username","admin");
attributes.append("channelno","0");
attributes.append("port","8080");
attributes.append("ip","1.1.1.1");
attributes.append("type","0");
attributes.append("name","costarIPC");
attributes.append("id","0");
writer.writeAttributes(attributes);
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
file.close();
qDebug()<<"finished writing!";
}
运行结果:
2、使用结构体保存相关信息
此处需要保存的信息结构一直,所以采用结构体。
//.h文件中定义
typedef struct{
QString version;
QString password;
QString username;
QString channelno;
QString port;
QString ip;
QString type;
QString name;
QString id;
}dev_info ;
void write_dev_xml_struct(QString dev_xml_dir,dev_info devinfo);//用结构体dev_info devinfo写入数据
dev_info devinfo;//使用定义的设备参数结构体
//自定义一个设备信息用于写入、读出测试
devinfo.id=QString("1");
devinfo.ip=QString("100,100,100,100");
devinfo.name=QString("test1");
devinfo.port=QString("8000");
devinfo.type=QString("0");
devinfo.version=QString("1");
devinfo.password=QString("1");
devinfo.username=QString("test_user_1");
devinfo.channelno=QString("1");
//
//用结构体导入数据
//dev_xml_dir:生成的xml文件地址 devinfo:以结构体形式存储的具体信息
void devmanager::write_dev_xml_struct(QString dev_xml_dir,dev_info devinfo)//
{
QFile file(dev_xml_dir);//
if(!file.open(QFile::WriteOnly|QFile::Text|QFile::Truncate))
{
qDebug()<<"cannot open file to write";
}
else
{
qDebug()<<"write file opened!";
}
QXmlStreamWriter writer;
QXmlStreamAttributes attributes; //QXmlStreamAttributes,而非QXmlStreamAttribute
writer.setCodec("UTF-8");
writer.setDevice(&file);
writer.setAutoFormatting(true);//自动格式
writer.writeStartDocument();
writer.writeStartElement("root");
writer.writeStartElement("device");
qDebug()<<"for"<<devinfo.version; //for "1"
attributes.append("version",devinfo.version);
attributes.append("password",devinfo.password);
attributes.append("username",devinfo.username);
attributes.append("channelno",devinfo.channelno);
attributes.append("port",devinfo.port);
attributes.append("ip",devinfo.ip);
attributes.append("type",devinfo.type);
attributes.append("name",devinfo.name);
attributes.append("id",devinfo.id);
writer.writeAttributes(attributes);
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
file.close();
qDebug()<<"finished writing!";
}
https://www.qter.org/forum.php?mod=viewthread&tid=11953
https://blog.csdn.net/l1216766050/article/details/84935752
上面使用的流不能实现增删的功能
#include //
#include //
void write_dom_xml(QString dev_xml_dir);//写入
//使用QDomDocument将数据写入xml
//dev_xml_dir:xml文件地址
void devmanager::write_dom_xml(QString dev_xml_dir)
{
QFile file(dev_xml_dir);//用绝对、相对路径打开文件
if(!file.open(QFile::WriteOnly|QFile::Truncate))//Truncate表示清空原来的内容
{
qDebug()<<"open xml failed!";
}
QDomDocument doc;
QDomProcessingInstruction instruction;
instruction=doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
//添加根节点
QDomElement root=doc.createElement("root");
doc.appendChild(root);
//添加第一个子节点device及其子元素
QDomElement device=doc.createElement("device");
device.setAttribute("id",0); //方式一:创建属性 其中键值对的值可以是各种类型
QDomAttr name=doc.createAttribute("name"); //方式二:创建属性 值必须是字符串
name.setValue("costarIPC");
device.setAttributeNode(name);
device.setAttribute("type","0");
device.setAttribute("ip","1.1.1.1");
device.setAttribute("port","0");
device.setAttribute("channelno","0");
device.setAttribute("username","admin");
device.setAttribute("password","admin508");
device.setAttribute("version"," ");
root.appendChild(device);
QTextStream output_stream(&file);
doc.save(output_stream,4);//缩进4格
file.close();
}
所有的节点用doc.createElement()创建,然后用appendchild将其添加到目标节点后面。
void read_dom_xml(QString dev_xml_dir);//其它设置同上
//读取.xml文件
//dev_xml_dir:xml文件地址
void devmanager::read_dom_xml(QString dev_xml_dir)
{
QFile file(dev_xml_dir); //打开
if(!file.open(QFile::ReadOnly))
{
qDebug()<<"failed to open!";
}
else
{
qDebug()<<"open file!";
}
QDomDocument doc;
if(!doc.setContent(&file)) //读取
{
file.close();
qDebug()<<"failed";
}
file.close();
QDomElement root=doc.documentElement();//返回根节点
qDebug()<<"root.nodename: "<<root.nodeName(); //root
QDomNode node=root.firstChild();
qDebug()<<"root.firstchild:"<<node.nodeName(); //device
while(!node.isNull())
{
if(node.isElement())
{
QDomElement element=node.toElement(); //device由node转为element
qDebug()<<"elemnt.tagname: "<<element.tagName();
for(int i=0;i<element.attributes().count();i++)
{
QDomNode attribute=element.attributes().item(i);
qDebug()<<attribute.nodeName()<<" : "<<attribute.nodeValue();
}
QDomNodeList nodelist=element.childNodes();//device下没有子节点,所以以下不会执行
for(int i=0;i<nodelist.count();i++)
{
QDomNode nod=nodelist.at(i);
qDebug()<<"nodelist.count= "<<nodelist.count()<<"at "<<i;
if(nod.isElement())
{
qDebug()<<nod.nodeName()<<":"<<nod.toElement().text();
}
}
}
node=node.nextSibling();//下一个兄弟节点,nextSiblingElement()是下一个兄弟元素
}
}
void add_dom_xml(QString dev_xml_dir);//增加,其它设置同上
//在已有的xml文件中添加新一行元素
//dev_xml_dir:xml文件地址
void devmanager::add_dom_xml(QString dev_xml_dir)//,dev_info devinfo
{
//打开文件
QFile file(dev_xml_dir);
if(!file.open(QFile::ReadOnly))
{
qDebug()<<"failed to open file!";
}
else
{
qDebug()<<"open file!";
}
QDomDocument doc;
if(!doc.setContent(&file))
{
qDebug()<<"doc.setconten";
}
file.close();
//找到节点,添加元素
QDomElement root=doc.documentElement();//根节点
QDomElement device_add=doc.createElement("device");//1级子节点
device_add.setAttribute("id","2"); //
device_add.setAttribute("name","costarIPC2");
device_add.setAttribute("type","0");
device_add.setAttribute("ip","2.2.2.2");
device_add.setAttribute("port","2");
device_add.setAttribute("channelno","2");
device_add.setAttribute("username","admin2");
device_add.setAttribute("password","admin222");
device_add.setAttribute("version"," ");
root.appendChild(device_add);
if(!file.open(QFile::WriteOnly|QFile::Truncate))//先读进来,再用truncate重写
{
qDebug()<<"open failed to truncate";
}
QTextStream output_stream(&file);
doc.save(output_stream,4);//缩进4格
file.close();
}
void rem_dom_xml(QString dev_xml_dir);//删除,其它设置同上
//从xml文档中删除一行元素
//dev_xml_dir:xml文件地址
void devmanager::rem_dom_xml(QString dev_xml_dir)
{
//打开
QFile file(dev_xml_dir);
if(!file.open(QFile::ReadOnly))
{
qDebug()<<"failed to open!";
} else
{
qDebug()<<"opend!";
}
QDomDocument doc;
if(!doc.setContent(&file))
{
qDebug()<<"doc.setcontent";
}
file.close();
QDomElement root=doc.documentElement();
QDomNodeList no_list=doc.elementsByTagName("device");
for(int i=0;i<no_list.count();i++)
{
QDomElement element=no_list.at(i).toElement();//将device由node转换为element
if(element.attribute("id")=="2")
{
root.removeChild(no_list.at(i));//此处的element为device,是root的child
}
}
if(!file.open(QFile::WriteOnly|QFile::Truncate))
{
qDebug()<<"failed to write!";
}
QTextStream output_stream(&file);
doc.save(output_stream,4);
file.close();
}
以序号判断元素不可行,因为xml显示的顺序和xml结构里的节点顺序是不一致的。
void devmanager::update_dom_xml(QString dev_xml_dir)
{
QFile file(dev_xml_dir);
if(!file.open(QFile::ReadOnly))
{
qDebug()<<"failed to open!";
}
else
{
qDebug()<<"opened!";
}
QDomDocument doc;
if(!doc.setContent(&file))
{
qDebug()<<"failed doc.setcontent";
}
file.close();
QDomElement root=doc.documentElement();
QDomNodeList list=root.elementsByTagName("device"); //2行device数据
QDomNode node=list.at(0); //id=0的device行
qDebug()<<"device.list(0):"<<node.nodeName(); //device
QDomElement node_ele=node.toElement();
qDebug()<<"new value"<<node_ele.attribute("name");
node_ele.setAttribute("name","tttest");
qDebug()<<"new value"<<node_ele.attribute("name");
if(!file.open((QFile::WriteOnly|QFile::Truncate)))
{
return;
}
QTextStream output_stream(&file);
doc.save(output_stream,4);
file.close();
}
void update_dom_xml(QString dev_xml_dir,dev_info devinfo);// 更新
//新的数据行,更换旧的数据行
//dev_xml_dir:xml文件地址 devinfo:设备信息
void devmanager::update_dom_xml(QString dev_xml_dir,dev_info devinfo)
{
QFile file(dev_xml_dir);
if(!file.open(QFile::ReadOnly))
{
qDebug()<<"failed to open!";
}
else
{
qDebug()<<"opened!";
}
QDomDocument doc;
if(!doc.setContent(&file))
{
qDebug()<<"failed doc.setcontent";
}
file.close();
//根据devinfo的信息形成新的node
QDomElement attributes=doc.createElement("device");
attributes.setAttribute("version",devinfo.version);
attributes.setAttribute("password",devinfo.password);
attributes.setAttribute("username",devinfo.username);
attributes.setAttribute("channelno",devinfo.channelno);
attributes.setAttribute("port",devinfo.port);
attributes.setAttribute("ip",devinfo.ip);
attributes.setAttribute("type",devinfo.type);
attributes.setAttribute("name",devinfo.name);
attributes.setAttribute("id",devinfo.id);
// QDomNode new_node=attributes.toNotation();
//查找old_node
QDomElement root=doc.documentElement();
QDomNodeList list=root.elementsByTagName("device"); //2行device数据
QDomNode old_node=list.at(0); //id=0的device行
root.replaceChild(attributes,old_node);
if(!file.open((QFile::WriteOnly|QFile::Truncate)))
{
return;
}
QTextStream output_stream(&file);
doc.save(output_stream,4);
file.close();
}