通过项目的开发,我发现xml的读写主要是分为以下几种类型: 一种类型是:
<?xml version="1.0" encoding="UTF-8"?> <POIS> <POI LightMode="head_light" ShowUnderground="true" name="位置1 经度:89.9998 纬度:0"/> </POIS>这种情况是只有一个根节点,下来就是相同的子节点;对于这种情况,xml的读写是下面这样子的:
//xml文件在电脑中放置的路径 QString xmlPath = FileUtils::getInstance()->getConfigPath("./xmls/PoiPoints.xml"); //根节点的加载 QDomDocument dom; //加载xml文件 QFile xmlFile(xmlPath); //判断xml是否打开 if (!xmlFile.open(QIODevice::ReadOnly)) { LOG_FAILD(L"open file initiative poi failed."); xmlFile.close(); return; } //判断xml设置文件名 if (!dom.setContent(&xmlFile)) { LOG_FAILD(L"read initiative poi as xml content failed."); xmlFile.close(); return; } //xml文件的关闭,这步必须得有,如果没有,读取xml是不起作用的 xmlFile.close(); //读取xml的根节点(相对于本实例就是POIS) QDomElement root=dom.documentElement(); //读取根节点的子节点(相对于本实例就是POI) QDomElement element =root.firstChildElement(); QString name, lightMode, showUnderground; bool bShowUnderground = false; POIType* poiType; //循环读取根节点的子节点 while (true) { //这步是必须的 if (element.isNull()) break; //通过子节点的名字来判断子节点里面的元素 if (element.tagName().compare("POI", Qt::CaseInsensitive) == 0) { name = element.attribute("name"); lightMode = element.attribute("LightMode"); showUnderground = element.attribute("ShowUnderground", "false"); bShowUnderground = showUnderground.compare("true", Qt::CaseInsensitive) == 0; poiType = new POIType(name, lightMode, bShowUnderground); } //hashPOI是一个哈希表 hashPOI.insert(name, poiType); //进行下一个子节点,这步也是必须的 element = element.nextSiblingElement(); }一种类型是:
<?xml version="1.0" encoding="utf-8"?> <DataModel> <ObjectType Name="GDJT_SB" Header="设备" Caption="设备" Table="GDJT_SB" Icon="Ventilator" InfoLogoIcon="INFO_SB"> <Field Name="ID" Header="标识" Caption ="" Column="" DataType="" SystemType="Id" PresentType="VisibleInDetail" OrderByType="Asc1" Editor="IDEditor" EditorParams=""/> <Field Name="ID_3D" Header="场景ID" Caption ="" Column="" DataType="" SystemType="ID_3D" PresentType="VisibleInDetail"/> </ObjectType> <ObjectType Name="GDJT_WXJL" Header="维修记录" Caption="" Table="GDJT_WXJL" Icon="Clear" InfoLogoIcon=""> <Field Name="ID" Header="标识" Caption ="" Column="" DataType="" SystemType="Id" PresentType="VisibleInDetail" OrderByType="Asc1" Editor="IDEditor" EditorParams=""/> <Field Name="BH" Header="编号" Caption ="" Column="" DataType="" SystemType="Name" PresentType=""/> </ObjectType> </DataModel>这种情况是有一个根节点,有几个并列的根节点下面的子节点,还有几个根节点下面子节点的子节点,对于这种xml的读取,读取的方法是:
//获取xml所在的文件夹的路径 QString xmlDir = FileUtils::getInstance()->getConfigPath("Xmls/TypedMetaDatas"); //读取xml所在的文件夹 QDir dir(xmlDir); //获取xml所在的路径 QString xmlFilePath = xmlDir + QDir::separator() + xmlFilePath; //获取xml文件 QDomDocument dom; //加载xml的文件路径 QFile xmlFile(xmlPath); //判断xml是否打开 if (!xmlFile.open(QIODevice::ReadOnly)) { xmlFile.close(); return; } //判断xml的目录 if (!dom.setContent(&xmlFile)) return; //xml文件的关闭,这步必须得有,如果没有,读取xml是不起作用的 xmlFile.close(); //读取xml的根节点(相对于本实例就是DataModel) QDomElement root=dom.documentElement(); //读取根节点的子节点(相对于本实例就是ObjectType) QDomElement objectTypeElement =root.firstChildElement(); QString name, header, caption, table, icon, logoIcon, column, dataType, systemType, presentType,preferWidth, orderByType,editor,editorParams,classifyType,defaultClassify; //循环读取根节点的子节点 while (true) { //这步是必须的 if (objectTypeElement.isNull()) break; //获取objectType节点中的name属性 name = objectTypeElement.attribute("Name"); if (!name.isEmpty()) { header = objectTypeElement.attribute("Header", name); caption = objectTypeElement.attribute("Caption", header); table = objectTypeElement.attribute("Table",name); if (table.isNull() || table.isEmpty()) { table = name; } icon = objectTypeElement.attribute("Icon"); logoIcon = objectTypeElement.attribute("InfoLogoIcon"); //获取objectType下面的子节点(本实例中就是Field) QDomElement fieldElement = objectTypeElement.firstChildElement(); while (true) { if (fieldElement.isNull()) break; if (fieldElement.tagName() == "Field") { name = fieldElement.attribute("Name"); header = fieldElement.attribute("Header", name); caption = fieldElement.attribute("Caption", header); column = fieldElement.attribute("Column", name); dataType = fieldElement.attribute("DataType", "String"); systemType = fieldElement.attribute("SystemType", "Custom"); presentType = fieldElement.attribute("PresentType", "VisibleInDetail | EditNone"); preferWidth = fieldElement.attribute("PreferWidth"); orderByType = fieldElement.attribute("OrderByType", "None"); editor = fieldElement.attribute("Editor"); editorParams = fieldElement.attribute("EditorParams"); classifyType = fieldElement.attribute("ClassifyType"); defaultClassify = fieldElement.attribute("DefaultClassify"); } fieldElement = fieldElement.nextSiblingElement(); } } objectTypeElement = objectTypeElement.nextSiblingElement(); } ********************************************************************************xml的写入,也可以分为几种情况: 一种情况:
<?xml version="1.0" encoding="UTF-8"?> <POIS> <POI LightMode="head_light" ShowUnderground="true" name="位置1 经度:89.9998 纬度:0"/> </POIS>这是一个根节点,一个子节点,这种xml的写入的写法为:
QString xmlPath = FileUtils::getInstance()->getConfigPath("./xmls/PoiPoints.xml"); QDomDocument dom; QFile xmlFile(xmlPath); if (!xmlFile.open(QIODevice::ReadOnly)) { LOG_FAILD(L"open file initiative nav failed."); xmlFile.close(); return; } if (!dom.setContent(&xmlFile)) { LOG_FAILD(L"read initiative nav as xml content failed."); xmlFile.close(); return; } xmlFile.close(); QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\""); dom.appendChild(instruction); QDomElement root = dom.createElement("POIS"); dom.appendChild(root); QDomElment node=root.createElement("POI"); root.appendChild(node); root.setAttribute("name", "位置1 经度:89.9998 纬度:0"); root.setAttribute("LightMode", lightMode); root.setAttribute("ShowUnderground", ShowUnderground); QFile file("PoiPoints.xml"); //以下几步很重要,在写入之后一定要保存,不然xml的写入不起作用 if (!filexml.open(QFile::WriteOnly | QFile::Truncate)) return; QTextStream ts(&filexml); ts.reset(); ts.setCodec("utf-8"); dom.save(ts, 4, QDomNode::EncodingFromTextStream); filexml.close();一种情况是:
<?xml version="1.0" encoding="UTF-8"?> <POIS> <POI> <ShowUnderground>"true"</ShowUnderground> <LightMode>"head_light"</LightMode> <name>"位置1 经度:89.9998 纬度:0"</name> </POI> </POIS>这是一个根节点,一个根节点下面有一个子节点,一个子节点下面有很多子节点:
QString xmlPath = FileUtils::getInstance()->getConfigPath("./xmls/PoiPoints.xml"); QDomDocument dom; QFile xmlFile(xmlPath); if (!xmlFile.open(QIODevice::ReadOnly)) { LOG_FAILD(L"open file initiative nav failed."); xmlFile.close(); return; } if (!dom.setContent(&xmlFile)) { LOG_FAILD(L"read initiative nav as xml content failed."); xmlFile.close(); return; } xmlFile.close(); QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\""); dom.appendChild(instruction); QDomElement root = dom.createElement("POIS"); dom.appendChild(root); QDomElment node=root.createElement("POI"); root.appendChild(node); QDomElement nameNode=dom.createElement("name"); node.appendChild(nameNode); QDomText nameText=dom.createTextNode("位置1 经度:89.9998 纬度:0"); QFile file("PoiPoints.xml"); //以下几步很重要,在写入之后一定要保存,不然xml的写入不起作用 if (!filexml.open(QFile::WriteOnly | QFile::Truncate)) return; QTextStream ts(&filexml); ts.reset(); ts.setCodec("utf-8"); dom.save(ts, 4, QDomNode::EncodingFromTextStream); filexml.close();