最近做项目需要做很多零散的配置写入文件,首先想到xml文件的存储。搜索了很多相关的文章,看的我有点乱,所以自己总结一下。
这里由于存储数据不大,所以用Dom方式进行读写xml。
这里我在写入项目之前,首先写了一个简单的例子:
本次用到xml操作有三个写入,读取,修改。
下面是我写的测试代码,代码都是经过运行测试的,可用。
1、写入测试代码:
// 1. 创建节点,将其写入XML文件,主要操作包括:
// 1).创建根节点:QDomElement root = doc.documentElement("rootName " );
// 2).创建元素节点:QDomElement element = doc.createElement("nodeName");
// 3).添加元素节点到根节点:root. appendChild(element);
// 4).创建元素文本:QDomText nodeText=doc.createTextNode("text");
// 5).添加元素文本到元素节点:element. appendChild(nodeText);
void testxml::writeXml()
{
QDomDocument doc;
QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
QDomElement root = doc.createElement("configure");
doc.appendChild(root);
QDomElement note = doc.createElement("pingIP");
root.appendChild(note);
QDomText nodeText=doc.createTextNode("192.168.1.1");
note.appendChild(nodeText);
QDomElement no = doc.createElement("network");
root.appendChild(no);
QDomElement ipaddr = doc.createElement("ipaddr");
no.appendChild(ipaddr);
QDomText ipaddrText=doc.createTextNode("192.168.1.81");
ipaddr.appendChild(ipaddrText);
QDomElement netmask = doc.createElement("netmask");
no.appendChild(netmask);
QDomText netmaskText=doc.createTextNode("255.255.255.0");
netmask.appendChild(netmaskText);
QDomElement DefaultGw = doc.createElement("DefaultGw");
no.appendChild(DefaultGw);
QDomText DefaultGwText=doc.createTextNode("192.168.1.1");
DefaultGw.appendChild(DefaultGwText);
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();
}
2、读取测试代码
// 1).读取根节点:QDomElement root = doc.documentElement();
// 2).读取第一个子节点:QDomNode node = root.firstChild();
// 3).读取下一个子节点:node = node.nextSibling();
// 4).匹配结点标记:node.toElement().tagName() == "note"
// 5).读取节点文本:no = childNode.toText().data();
void testxml::readXml()
{
QFile file("test.xml");
if (!file.open(QFile::ReadOnly | QFile::Text))
{
qDebug() << "read only return";
return ;
}
QString errorStr;
int errorLine;
int errorColumn;
QDomDocument doc;
if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))
{
return ;
}
file.close();
QDomElement root = doc.documentElement();
QDomNode node = root.firstChild();
while (!node.isNull())
{
if (node.toElement().tagName() == "pingIP")
{
qDebug() <<"pingIP"<< node.firstChild().toText().data();
}
else if (node.toElement().tagName() == "network")
{
QDomNode childNode = node.firstChild();
if (childNode.toElement().tagName() == "ipaddr")
{
qDebug() << "ipaddr"<<childNode.firstChild().toText().data();
}
}
node = node.nextSibling();//读取兄弟节点
}
}
3、修改xml节点测试代码
void testxml::changeXml()
{
QFile file("test.xml");
if (!file.open(QIODevice::ReadOnly |QIODevice::Text))
{
return ;
}
QString errorStr;
int errorLine;
int errorColumn;
QDomDocument doc;
if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn))
{
return ;
}
file.close();
QDomElement root = doc.documentElement();
QDomNode node = root.firstChild();
while (!node.isNull())
{
if (node.toElement().tagName() == "network")
{
QDomNode childNode = node.firstChild();
if (childNode.toElement().tagName() == "ipaddr")
{
childNode.firstChild().setNodeValue("121.199.19.139");
//QDomNode newnode= childNode.firstChild();
//childNode.replaceChild(newnode,oldnode);
}
}
node = node.nextSibling();//读取兄弟节点
}
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();
}
修改xml的部分看到网上有的资料说需要这样做:
QDomNode childNode = node.firstChild();
if (childNode.toElement().tagName() == "ipaddr")
{
QDomNode oldnode= childNode.firstChild();
childNode.firstChild().setNodeValue("121.199.19.139");
QDomNode newnode= childNode.firstChild();
childNode.replaceChild(newnode,oldnode);
}
这里用到了replaceChild 函数进行替换节点操作的,我觉得比较繁琐,所以直接这样:
QDomNode childNode = node.firstChild();
if (childNode.toElement().tagName() == "ipaddr")
{
childNode.firstChild().setNodeValue("121.199.19.139");
}
其实这样也实现了此功能,测试了完全可以,对于为什么资料上都要写节点替换,不是特别清楚。望高手解答。
XML的简单操作就这些,如有问题请大家多多指教。