qt中關於xml的讀取、寫入、修改等操作
阿新 • • 發佈:2019-02-04
通過專案的開發,我發現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();