1. 程式人生 > >qt中關於xml的讀取、寫入、修改等操作

qt中關於xml的讀取、寫入、修改等操作

通過專案的開發,我發現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();