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();
  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以使用QTreeWidget类来创建一个树形控件。要将QTreeWidget的数据写入XML文件,可以使用QXmlStreamWriter类。以下是一个简单的示例代码: ```c++ QTreeWidget* treeWidget = new QTreeWidget(); // 添加树形控件的节点和子节点 // ... QFile file("data.xml"); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QXmlStreamWriter writer(&file); writer.setAutoFormatting(true); writer.writeStartDocument(); writer.writeStartElement("data"); // 遍历树形控件的节点和子节点,将数据写入XML文件 for (int i = ; i < treeWidget->topLevelItemCount(); i++) { QTreeWidgetItem* item = treeWidget->topLevelItem(i); writer.writeStartElement("item"); writer.writeAttribute("name", item->text()); for (int j = ; j < item->childCount(); j++) { QTreeWidgetItem* childItem = item->child(j); writer.writeStartElement("child"); writer.writeAttribute("name", childItem->text()); writer.writeEndElement(); // child } writer.writeEndElement(); // item } writer.writeEndElement(); // data writer.writeEndDocument(); file.close(); } ``` 在上面的代码,我们首先创建了一个QTreeWidget对象,并添加了一些节点和子节点。然后,我们创建了一个QFile对象,用于将数据写入XML文件。接下来,我们使用QXmlStreamWriter类来写入XML文件。我们首先调用writeStartDocument()方法来写入XML文档的开始标记。然后,我们使用writeStartElement()方法来写入根元素的开始标记。在这个例子,我们将根元素命名为"data"。接着,我们遍历树形控件的节点和子节点,并使用writeStartElement()方法来写入每个元素的开始标记。我们还使用writeAttribute()方法来写入元素的属性。最后,我们使用writeEndElement()方法来写入每个元素的结束标记。在写入完所有的元素后,我们使用writeEndElement()方法来写入根元素的结束标记。最后,我们调用writeEndDocument()方法来写入XML文档的结束标记。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值