引言:
这是小编写的一篇基于Android XML数据解析的博客,里面讲了一些基础的XML 格式和语法
在这我就不讲那些最基础的知识了,如果大家对XML一点也不了解的话,可以到上面的链接中学习学习。
一、XML文件解析步骤
(1)、首先需要找到指定目录下的XML文件。
(2)、创建一个QDomDocument对象用于绑定这个打开的XML文件。
(3)、创建一个QDomElement对象用于接收XML中的根元素,因为我们这个解析是从它的根元素出发开始找的。
(4)、创建一个QDomNodeList容器对象,用于存放根元素的孩子节点,例如:元素:<element>
。然后通过遍历孩子节点下面的其他节点,并将其值保存下来以便日后使用。
(5)、然后将相应的值进行类型转换添加到map容器中,然后通过遍历容器中的内容便可得到相应的值。这里提到了STL标准模板库STL标准模板库汇总详解
二、XML解析详解
2.1、XML格式案例
<?xml version="1.0" encoding="GBK"?>
<elements>
<element>
<name>AlarmSettingVisibility</name>
<int>31</int>
</element>
<element>
<name>cloudatlasdemooffset</name>
<int>0</int>
</element>
<element>
<name>lookatbuildinganglexy</name>
<int>10</int>
</element>
<element>
<name>lookatbuildinganglexz</name>
<int>270</int>
</element>
<element>
<name>lookatbuildingdistance</name>
<int>700</int>
</element>
<element>
<name>lookatdeviceanglexy</name>
<int>5</int>
</element>
<element>
<name>lookatdeviceanglexz</name>
<int>0</int>
</element>
<element>
<name>lookatinsertanglexy</name>
<int>5</int>
</element>
<element>
<name>lookatinsertanglexz</name>
<int>0</int>
</element>
<element>
<name>maxmapcachenumber</name>
<int>3</int>
</element>
<element>
<name>openlog</name>
<int>1</int>
</element>
<element>
<name>AlarmSettingLv0</name>
<float>1</float>
</element>
<element>
<name>AlarmSettingLv1</name>
<float>1</float>
</element>
<element>
<name>AlarmSettingLv2</name>
<float>1</float>
</element>
<element>
<name>AlarmSettingLv3</name>
<float>1</float>
</element>
<element>
<name>AlarmSettingLv4</name>
<float>1</float>
</element>
<element>
<name>lookatdevicedistance</name>
<float>5</float>
</element>
<element>
<name>lookatinsertdistance</name>
<float>1.6</float>
</element>
<element>
<name>CookieHeader</name>
<qstring>session="+Ph7o0/8TTwV1mUN15lE12BAIQA=?user_id=STEKLg=="</qstring>
</element>
<element>
<name>LastUpdateTick</name>
<qstring>1460368713</qstring>
</element>
<element>
<name>URLHost</name>
<qstring>http://demo.3ddcim.com/</qstring>
</element>
</elements>
2.2、解析源代码
2.2.1、容器对象的定义
QMap<QString,int> _intValueMap;
QMap<QString,float> _floatValueMap;
QMap<QString,QString> _qstringValueMap;
QMap<QString,osg::Vec2> _vec2ValueMap;
QMap<QString,osg::Vec3> _vec3ValueMap;
QMap<QString,osg::Vec4> _vec4ValueMap;
QString _filePath;
2.2.2、XML数据解析方法
bool ConfigFileOperation::loadConfigFile(const QString& file)
{
QFile xmlFile(file+"\\"+DEFAULT_CONFIG_FILENAME);
if(!xmlFile.open(QIODevice::ReadWrite))
{
return false;
}
_filePath = file;
QDomDocument domtree;
if(!domtree.setContent(&xmlFile))
{
xmlFile.close();
return false;
}
//clearAll();
QDomElement root = domtree.documentElement();
QDomNodeList nodelist=root.childNodes();
int count=nodelist.length();
for(int i=0;i<nodelist.length();++i)
{
QDomNode childnode = nodelist.item(i);
if(childnode.nodeName() == "element")
{
QString name = "";
QString value = "";
QString valuetype = "";
for(int j=0;j< childnode.childNodes().length();j++)
{
if(childnode.childNodes().item(j).nodeName() == XML_ELEMENT_NAME)
{
name = childnode.childNodes().item(j).toElement().text();
}
else
{
valuetype = childnode.childNodes().item(j).nodeName();
value = childnode.childNodes().item(j).toElement().text();
}
}
if(name!="" && value!="" && valuetype!="")
add(name,valuetype,value);
}
xmlFile.close();
return true;
}
2.2.3、将解析的数据进行类型转换并保存到对应的容器中
void ConfigFileOperation::add(const QString& name,const QString& valuetype,const QString& value)
{
if(_intValueMap.contains(name) || _floatValueMap.contains(name) ||_qstringValueMap.contains(name) ||
_vec2ValueMap.contains(name) ||_vec3ValueMap.contains(name) ||_vec4ValueMap.contains(name))
return;
if(valuetype == "int")
{
int intvalue = value.toInt();
addIntValue(name,intvalue);
}
else if(valuetype == "float")
{
float floatvalue = value.toFloat();
addfloatValue(name,floatvalue);
}
else if(valuetype == "qstring")
{
addQStringValue(name,value);
}
else if(valuetype == "vec2")
{
QStringList list = value.split(" ",QString::SkipEmptyParts);
if(list.size() == 2)
{
osg::Vec2 vec2(list.at(0).toFloat(),list.at(1).toFloat());
addVec2Value(name,vec2);
}
}
else if(valuetype == "vec3")
{
QStringList list = value.split(" ",QString::SkipEmptyParts);
if(list.size() == 3)
{
osg::Vec3 vec3(list.at(0).toFloat(),list.at(1).toFloat(),list.at(2).toFloat());
addVec3Value(name,vec3);
}
}
else if(valuetype == "vec4")
{
QStringList list = value.split(" ",QString::SkipEmptyParts);
if(list.size() == 4)
{
osg::Vec4 vec4(list.at(0).toFloat(),list.at(1).toFloat(),list.at(2).toFloat(),list.at(3).toFloat());
addVec4Value(name,vec4);
}
}
}
2.2.4、将数据添加到容器对象中,这里举一个例子其他都是一样的原理
void ConfigFileOperation::addIntValue(const QString& name,int value)
{
if(!_intValueMap.contains(name))
_intValueMap.insert(name,value);
_intValueMap[name] = value;
}
2.2.5、将数据插入到XML文件中
bool ConfigFileOperation::writeConfigFile(const QString& filePath)
{
QString file = filePath;
if(file == "")
file = _filePath;
QFile xmlFile(file+"\\"+DEFAULT_CONFIG_FILENAME);
if(!xmlFile.open(QIODevice::WriteOnly|QIODevice::Text))
{
//log
return false;
}
QDomDocument domtree;
QDomText text;
domtree.documentElement().clear();
QDomProcessingInstruction instruction;
instruction = domtree.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
domtree.appendChild( instruction);
//map
QDomElement mapelement = domtree.createElement("elements");
domtree.appendChild(mapelement);
//intmap
QMap<QString,int>::Iterator intiter = _intValueMap.begin();
for(;intiter!=_intValueMap.end();++intiter)
{
QDomElement intelement = domtree.createElement("element");
mapelement.appendChild(intelement);
//name
QDomElement intnameelement = domtree.createElement(XML_ELEMENT_NAME);
intelement.appendChild(intnameelement);
text = domtree.createTextNode(intiter.key());
intnameelement.appendChild(text);
//value
QDomElement intvalueelement = domtree.createElement("int");
intelement.appendChild(intvalueelement);
text = domtree.createTextNode(QString::number(intiter.value()));
intvalueelement.appendChild(text);
}
//floatmap
QMap<QString,float>::Iterator floatiter = _floatValueMap.begin();
for(;floatiter!=_floatValueMap.end();++floatiter)
{
QDomElement floatelement = domtree.createElement("element");
mapelement.appendChild(floatelement);
//name
QDomElement floatnameelement = domtree.createElement(XML_ELEMENT_NAME);
floatelement.appendChild(floatnameelement);
text = domtree.createTextNode(floatiter.key());
floatnameelement.appendChild(text);
//value
QDomElement floatvalueelement = domtree.createElement("float");
floatelement.appendChild(floatvalueelement);
text = domtree.createTextNode(QString::number(floatiter.value()));
floatvalueelement.appendChild(text);
}
//qstring
QMap<QString,QString>::Iterator qstringiter = _qstringValueMap.begin();
for(;qstringiter!=_qstringValueMap.end();++qstringiter)
{
QDomElement qstringelement = domtree.createElement("element");
mapelement.appendChild(qstringelement);
//name
QDomElement qstringnameelement = domtree.createElement(XML_ELEMENT_NAME);
qstringelement.appendChild(qstringnameelement);
text = domtree.createTextNode(qstringiter.key());
qstringnameelement.appendChild(text);
//value
QDomElement qstringvalueelement = domtree.createElement("qstring");
qstringelement.appendChild(qstringvalueelement);
text = domtree.createTextNode(qstringiter.value());
qstringvalueelement.appendChild(text);
}
//vec2
QMap<QString,osg::Vec2>::Iterator vec2iter = _vec2ValueMap.begin();
for(;vec2iter!=_vec2ValueMap.end();++vec2iter)
{
QDomElement vec2element = domtree.createElement("element");
mapelement.appendChild(vec2element);
//name
QDomElement vec2nameelement = domtree.createElement(XML_ELEMENT_NAME);
vec2element.appendChild(vec2nameelement);
text = domtree.createTextNode(vec2iter.key());
vec2nameelement.appendChild(text);
//value
QDomElement vec2valueelement = domtree.createElement("vec2");
vec2element.appendChild(vec2valueelement);
QString vec2string = QString::number(vec2iter.value().x())+" "+QString::number(vec2iter.value().y());
text = domtree.createTextNode(vec2string);
vec2valueelement.appendChild(text);
}
//vec3
QMap<QString,osg::Vec3>::Iterator vec3iter = _vec3ValueMap.begin();
for(;vec3iter!=_vec3ValueMap.end();++vec3iter)
{
QDomElement vec3element = domtree.createElement("element");
mapelement.appendChild(vec3element);
//name
QDomElement vec3nameelement = domtree.createElement(XML_ELEMENT_NAME);
vec3element.appendChild(vec3nameelement);
text = domtree.createTextNode(vec3iter.key());
vec3nameelement.appendChild(text);
//value
QDomElement vec3valueelement = domtree.createElement("vec3");
vec3element.appendChild(vec3valueelement);
QString vec3string = QString::number(vec3iter.value().x())+" "+QString::number(vec3iter.value().y())+
" "+QString::number(vec3iter.value().z());
text = domtree.createTextNode(vec3string);
vec3valueelement.appendChild(text);
}
//vec4
QMap<QString,osg::Vec4>::Iterator vec4iter = _vec4ValueMap.begin();
for(;vec4iter!=_vec4ValueMap.end();++vec4iter)
{
QDomElement vec4element = domtree.createElement("element");
mapelement.appendChild(vec4element);
//name
QDomElement vec4nameelement = domtree.createElement(XML_ELEMENT_NAME);
vec4element.appendChild(vec4nameelement);
text = domtree.createTextNode(vec4iter.key());
vec4nameelement.appendChild(text);
//value
QDomElement vec4valueelement = domtree.createElement("vec4");
vec4element.appendChild(vec4valueelement);
QString vec4string = QString::number(vec4iter.value().r())+" "+QString::number(vec4iter.value().g())+
" "+QString::number(vec4iter.value().b())+" "+QString::number(vec4iter.value().a());
text = domtree.createTextNode(vec4string);
vec4valueelement.appendChild(text);
}
QTextStream out(&xmlFile);
domtree.save(out,4,QDomNode::EncodingFromTextStream);
xmlFile.close();
return true;
}