XML是一种很好的存储数据的文件。可以存储数据量较大的并且带有不同属性的内容,其中XML采用的是倒树形结构。由一个根节点往后蔓延多个孩子节点,
每个孩子节点下面又有多个孩子节点。每一个节点中又可设置Attribute。
QT中XML有两个常用的类QDOM和QXmlStream
读部分:QXmlStreamReader:
这里有一个关于这个类的详细介绍:http://blog.youkuaiyun.com/liang19890820/article/details/52808829
下面是我解析的DEMO
xml 原文件:tool_coords.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<config filename="tool_coords.cfg">
<tool_coord id="1">
<name>tool1</name>
<posx>0</posx>
<posy>0</posy>
<posz>0</posz>
<rotx>0</rotx>
<roty>0</roty>
<rotz>0</rotz>
<heavy>333</heavy>
<hposx>7</hposx>
<hposy>8</hposy>
<hposz>9</hposz>
<torx>10</torx>
<tory>11</tory>
<torz>12</torz>
<Point>
<Item U="" L="" Name="0" R="" S="" B="" T=""/>
<Item U="" L="" Name="1" R="" S="" B="" T=""/>
<Item U="" L="" Name="2" R="" S="" B="" T=""/>
<Item U="" L="" Name="3" R="" S="" B="" T=""/>
<Item U="" L="" Name="4" R="" S="" B="" T=""/>
</Point>
</tool_coord>
</config>
</root>
class XMLReadToolCoord{
public:
XMLReadToolCoord();
bool read(QIODevice *device);
QString errorString() const; //错误处理
toolCoord_s* getToolCoord();
signals:
public slots:
private:
void readRoot(); //读取根节点
void readConfig(); //读取config节点
void readToolCoord(int id); //读取tool_coord节点
void readPoint(int id); //读取Point节点
void readItem(int id); //读取5个关节点
QXmlStreamReader xml;
toolCoord_s tool_s[64];
};
XMLReadToolCoord::XMLReadToolCoord()
{
for(int i = 0; i < 64; i++){
tool_s[i].name = "";
tool_s[i].posx = "0";
tool_s[i].posy = "0";
tool_s[i].posz = "0";
tool_s[i].rotx = "0";
tool_s[i].roty = "0";
tool_s[i].rotz = "0";
tool_s[i].heavy = "0";
tool_s[i].hposx = "0";
tool_s[i].hposy = "0";
tool_s[i].hposz = "0";
tool_s[i].torx = "0";
tool_s[i].tory = "0";
tool_s[i].torz = "0";
for(int j = 0;j < 5; j++){
tool_s[i].pont[j].s = "";
tool_s[i].pont[j].l = "";
tool_s[i].pont[j].u = "";
tool_s[i].pont[j].r = "";
tool_s[i].pont[j].b = "";
tool_s[i].pont[j].t = "";
tool_s[i].pont[j].e1 = "";
tool_s[i].pont[j].e2 = "";
tool_s[i].pont[j].e3 = "";
tool_s[i].pont[j].e4 = "";
}
}
}
bool XMLReadToolCoord::read(QIODevice *device)
{
xml.setDevice(device);
if(xml.readNextStartElement())
{
QString strName = xml.name().toString();
if(strName == ROOT) //获取根元素
{
readRoot();
}
}
return !xml.error();
}
QString XMLReadToolCoord::errorString() const
{
return QString("Error:%1 Line:%2 Column:%3")
.arg(xml.errorString())
.arg(xml.lineNumber())
.arg(xml.columnNumber());
}
void XMLReadToolCoord::readRoot()
{
Q_ASSERT(xml.isStartElement() && xml.name().toString() == ROOT);
if (xml.readNextStartElement()) {
if (xml.name().toString() == CONFIG) {
readConfig();
}
}
}
void XMLReadToolCoord::readConfig()
{
Q_ASSERT(xml.isStartElement() && xml.name().toString() == CONFIG);
while (xml.readNextStartElement()){
if (xml.name().toString() == TOOLCOORD){
QXmlStreamAttributes attributes =xml.attributes();
if(attributes.hasAttribute("id")){
QString strId = attributes.value("id").toString();
qDebug() << QString("strId%1").arg(strId);
bool ok;
int id = strId.toInt(&ok) - 1;
if(ok)
readToolCoord(id);
}
}
else
xml.skipCurrentElement(); // 跳过当前元素
}
}
void XMLReadToolCoord::readToolCoord(int id)
{
// Q_ASSERT(xml.isStartElement()&& xml.name.toString() == TOOLCOORD);
while(xml.readNextStartElement()){
if(xml.name().toString() == NAME){
QString sName = xml.readElementText();
qDebug() << QString("name:%1").arg(sName);
tool_s[id].name = sName;
}
else if(xml.name().toString() == POSX){
QString sposx = xml.readElementText();
tool_s[id].posx = sposx;
}
else if(xml.name().toString() == POSY){
QString sposy = xml.readElementText();
tool_s[id].posy = sposy;
}
else if(xml.name().toString() == POSZ){
QString sposz = xml.readElementText();
tool_s[id].posz = sposz;
}
else if(xml.name().toString() == ROTX){
QString srotx = xml.readElementText();
tool_s[id].rotx = srotx;
}
else if(xml.name().toString() == ROTY){
QString sroty = xml.readElementText();
tool_s[id].roty = sroty;
}
else if(xml.name().toString() == ROTZ){
QString srotz = xml.readElementText();
tool_s[id].rotz = srotz;
}
else if(xml.name().toString() == HEAVY){
QString sheavy = xml.readElementText();
tool_s[id].heavy = sheavy;
}
else if(xml.name().toString() == HPOSX){
QString shposx = xml.readElementText();
tool_s[id].hposx = shposx;
}
else if(xml.name().toString() == HPOSY){
QString shposy = xml.readElementText();
tool_s[id].hposy = shposy;
}
else if(xml.name().toString() ==HPOSZ ){
QString shposz = xml.readElementText();
tool_s[id].hposz = shposz;
}
else if(xml.name().toString() == TORX){
QString storx = xml.readElementText();
tool_s[id].torx = storx;
}
else if(xml.name().toString() == TORY){
QString story = xml.readElementText();
tool_s[id].tory = story;
}
else if(xml.name().toString() == TORZ){
QString storz = xml.readElementText();
tool_s[id].torz = storz;
}
else if(xml.name().toString() == POINT){
readPoint(id);
}
else
xml.skipCurrentElement(); // 跳过当前元素
}
}
void XMLReadToolCoord::readPoint(int id)
{
Q_ASSERT(xml.isStartElement() && xml.name().toString() == POINT);
while(xml.readNextStartElement()){
if(xml.name().toString() == ITEM){
qDebug() << "ID" <<id<< endl;
readItem(id);
}
else
xml.skipCurrentElement(); // 跳过当前元素
qDebug() << xml.name().toString();
}
}
void XMLReadToolCoord::readItem(int id)
{
Q_ASSERT(xml.isStartElement() && xml.name().toString() == ITEM);
QXmlStreamAttributes attributes =xml.attributes();
// if(xml.name().toString() != ITEM) xml.skipCurrentElement(); // 跳过当前元素
if(attributes.hasAttribute("Name")){
QString sname = attributes.value("Name").toString();
bool ok;
int i = sname.toInt(&ok);
if(attributes.hasAttribute("S")){
QString s = attributes.value("S").toString();
tool_s[id].pont[i].s = s;
qDebug() <<"s:" + s;
}
if(attributes.hasAttribute("L")){
QString l = attributes.value("L").toString();
tool_s[id].pont[i].l = l;
qDebug() <<"l:" + l;
}
if(attributes.hasAttribute("U")){
QString u = attributes.value("U").toString();
tool_s[id].pont[i].u = u;
qDebug() <<"u:" + u;
}
if(attributes.hasAttribute("R")){
QString r = attributes.value("R").toString();
tool_s[id].pont[i].r = r;
}
if(attributes.hasAttribute("B")){
QString b = attributes.value("B").toString();
tool_s[id].pont[i].b = b;
qDebug() <<"b:" + b;
}
if(attributes.hasAttribute("T")){
QString t = attributes.value("T").toString();
tool_s[id].pont[i].t = t;
qDebug() <<"t:" + t;
}
}
if (xml.readNextStartElement()) {
if (xml.name().toString() != ITEM) {
xml.skipCurrentElement();
}
}
// qDebug() << "tool_s:"<<tool_s[0].pont[1].s
// <<tool_s[id].pont[1].l
// <<tool_s[id].pont[1].u
// <<tool_s[id].pont[1].r
// <<tool_s[id].pont[1].b
// <<tool_s[id].pont[1].t
// <<endl;
}
toolCoord_s* XMLReadToolCoord::getToolCoord()
{
return tool_s;
}
写部分:
QXmlStreamReader:
QDir d;
QString curpath = qApp->applicationDirPath() + CGlobal::g_dir ;
d.mkdir(curpath);
QString path =curpath + "origin_pos.xml";
QString strFile(path);
QFile file(strFile);
if(!file.open(QFile::WriteOnly | QFile::Text))
{
return;
}
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true); //自动化格式
writer.writeStartDocument("1.0", true); //开始文档(xml声明)
writer.writeStartElement("root"); //开始根元素
writer.writeStartElement("config"); //开始子元素
writer.writeAttribute("filename", "origin_pos.cfg");
writer.writeStartElement("origin_pos");
for(int i = 0; i < m_originList.size(); i++)
{
QString sjoint = QString("J%1").arg(i + 1);
writer.writeTextElement(sjoint, m_originList.at(i));
}
writer.writeEndElement();
writer.writeEndElement(); //结束子元素
writer.writeEndElement(); //结束根元素
writer.writeEndDocument(); //结束文档
file.close();
QDOM:
QDir d;
QString curpath = qApp->applicationDirPath() + CGlobal::g_dir ;
qDebug() << curpath << endl;
d.mkdir(curpath);
QString path =curpath + "spot.xml";
QString strFile(path);
QFile file(strFile);
QDomDocument doc;
if(!file.open( QFile::Text | QFile :: ReadWrite ))
{
qDebug() << "error::File to open file !\n" << endl;
return;
}
//将打开的文件与doc关联起来
if( !doc.setContent(&file) )
{
qDebug() << "error::ParserXML->OpenXmlFile->doc.setContent\n" << endl;
file.close();
return ;
}
file.close();
//获取XML文件中的root节点
QDomElement root = doc.documentElement();
qDebug() << root.tagName();
if(root.tagName()!= "root")
return ;
//获得config节点
QDomNode n_config = root.firstChild();
QDomElement e_config = n_config.toElement();
qDebug() << e_config.tagName();
//获得spot节点
QDomNode n_spot= e_config.firstChild();
QDomElement e_spot = n_spot.toElement();
qDebug() << e_spot.tagName();
//获得set节点
QDomNode n_set = e_spot.firstChild();
while(!n_set.hasChildNodes())
{
n_set = n_set.nextSibling();
}
QDomElement e_set = n_set.toElement();
qDebug() << e_set.tagName();
//获得set下的item节点
int i = 0;
QDomNode n_setItem = n_set.firstChild();
int count = n_set.childNodes().count();
qDebug() <<"count :" <<count;
while(count != 0)
{
if(n_setItem.hasAttributes())
{
qDebug() <<setDataList[i];
QDomText name = doc.createTextNode(setDataList[i]);
//先将ITEM中的节点删掉,再添加新的元素
n_setItem.removeChild(n_setItem.firstChild());
n_setItem.appendChild(name);
}
n_setItem = n_setItem.nextSibling();
count--;
i ++;
}
//获得curve节点
QDomNode n_curve = n_set.nextSibling();
while(!n_curve.hasChildNodes())
{
n_curve = n_curve.nextSibling();
}
QDomElement e_curve = n_curve.toElement();
qDebug() << e_curve.tagName();
//获得curve下的item节点
i = 0;
QDomNode n_curItem = n_curve.firstChild();
count = n_curve.childNodes().count();
qDebug() <<"count :" <<count;
while(count != 0)
{
if(n_curItem.hasAttributes())
{
n_curItem.toElement().setAttribute("torque", curveData[i].torque);
n_curItem.toElement().setAttribute("torque", curveData[i].press);
}
n_curItem = n_curItem.nextSibling();
count--;
i++;
}
//获得time节点
QDomNode n_time = n_curve.nextSibling();
QDomElement e_time = n_time.toElement();
qDebug() << e_time.tagName();
//将节点保存到XML文件
if(!file.open( QFile::Text | QFile :: WriteOnly ))
{
qDebug() << "error::File to open file !\n" << endl;
return;
}
QTextStream out(&file);
file.reset();
out.setCodec("UTF-8");
doc.save(out,4,QDomNode::EncodingFromTextStream);
file.close();
}