Qt 中的XML

XML的基本介绍:

在前端开发中:HTML是用来显示数据,而XML是用来传输和存储数据的

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签
  • XML 被设计为具有自我描述性
  • XML 是 W3C 的推荐标准

XML 应用于 web 开发的许多方面,常用于简化数据的存储和共享。

  • 通过 XML,可以在不兼容的系统之间轻松地交换数据。
  • XML 独立于硬件、软件以及应用程序,XML 使您的数据更可用,也更有用。
  • XML 数据以文本格式存储。这使得 XML 在不损失数据的情况下,更容易扩展或升级到新的操作系统、新应用程序或新的浏览器

 在Qt中的XML:

使用Qt XML模块来对XML文档进行处理

  1. 使用DOM方法对XML文档进行读/写
  2. SAX方法对XML进行存取(这种方法已经过时)
  3. 从Qt5开始,使用Qt Core中的QXmlStreamReaderQXmlStreamWriter,使用流的方式对XML文档进行读写。

XML文件的介绍:

<? xml version="1.0" encoding="UTF-8"?>//XML说明,version版本号,encoding版本号
<root>//根元素
   <id id="1">//元素 元素属性
       <name>王老五</name>//元素 内容
   </id>
   <id id="2">
       <name>张老四</name>
   </id>
</root>//结束

xml的一些内容: 

  1. 基本格式:<xxx>内容</xxx>
  2. XML有且仅有一个根元素      root 
  3. 元素: root  id   name
  4. 属性格式: <元素 元素=”属性“>
  5. 内容:<元素>text</元素>

DOM中XML的表示:

XML说明QDomProcessingInstruction
XML元素QDomElement
XML 属性QDomAttr
XML 内容QDomText
全部同一使用QDomNode

QDomNode 

isProcessingInstruction()判断是否为xml说明
isElement()判断是否为xml元素
isAttr()判断是否为xml属性
isText()判断是否为xml内容
toProcessingInstruction()转化为xml说明
toElement()转化为xml元素
toAttr()转化为xml属性
toText()转化为xml内容

QDomDocument(Dom文档类)

使用QDomDocument表示整个XML文档,提供对文档数据的主要访问。

使用时需要在pro文件中添加:

QT += xml

常用的函数:

toString(int indent=1)将分析的文档转换为文本的形式表示,1为缩进
toByteArray(int indent=1)将分析的文档转换回其文本表示形式,1为缩进
setContent()此函数从字节数组数据分析 XML 文档,并将其设置为文档的内容。它尝试按照 XML 规范的要求检测文档的编码。
importNode()节点导入节点从另一个文档导入到此文档。importedNode 保留在原始文档中;此函数创建可在此文档中使用的副本。
elementsByTagName()返回一个QDomNodeList,其中包含文档中具有名称标记名的所有元素。节点列表的顺序是它们在元素树的预序遍历中遇到的顺序。
elementById(QString id)返回根id匹配的元素
documentElement()返回文档的根元素
doctype()返回此文档的文档类型
createTextNode()为可以插入到文档树中的字符串创建一个文本节点
createProcessingInstruction()创建一个可以插入到文档中的新处理指令
createEntityReference(name)创建一个名为 name 的新实体引用,可以插入到文档中
createElementNS()创建一个具有命名空间支持的新元素,该元素可以插入到 DOM 树中。
createElemrnt(tagname)创建一个名为 tagName 的新元素,可以插入到 DOM 树中
createComment()为可以插入到文档中的字符串创建一个新注释
createAttributeNS()创建具有命名空间支持的新属性,该属性可以插入到元素中。
createAttribute(name)创建一个名为 name 的新属性,该属性可以插入到元素中

使用QDomDocument 读取xml中的数据:

  1. 创建一个QDomDocument对象
  2. 使用QFIle 打开xml文档
  3. 使用QDomDocument::setContent(file)把文件中的内容导入QDomDocument
  4. 使用QDocNode获取内容

首先创建一个xml文件,后缀为 .xml,然后把该文件添加到项目的资源文件中:

 xml文件中添加以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <id id="1">
       <name>wanglaowu</name>
   </id>
   <id id="2">
       <name>zhanglaosi</name>
   </id>
</root>

在main函数中添加以下代码:

#include <QApplication>
#include<QDomDocument>
#include<QMessageBox>
#include<QFile>
#include<QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    QDomDocument domdoc("myDom");//创建一个Dom文档对象
    QFile file(":/new/prefix1/XMLtext.xml");
    if(!file.open(QFile::ReadOnly))
    {
        QMessageBox::information(0,"提示信息","xml文件打开失败",QMessageBox::Ok);
        return 0;
    }
    if(!domdoc.setContent(&file))//读取文件内容到domdoc
    {
        file.close();
        return 0;
    }
    file.close();//读取完关闭文件
    QDomNode firstNode=domdoc.firstChild();//获取第一个元素,XML说明
    qDebug()<<qPrintable(firstNode.nodeName())//输出版本号
           <<qPrintable(firstNode.nodeValue());//输出编码类型


    return a.exec();
}

对于qPrintable的解释:

const char *qPrintable(const QString &str)

相当于:将 str 作为 .这相当于 str.toLocal8Bit().constData()

 输出xml中的全部内容:

 可以把XML看作一棵树:

    QDomElement docElem=domdoc.documentElement();//获取根元素
    QDomNode n=docElem.firstChild();//获取第一个子节点
    while(!n.isNull())//不为空的话
    {
        if(n.isElement())//如果是元素的话
        {
            QDomElement e=n.toElement();//获取该元素

            qDebug()<<qPrintable(e.tagName())//获取元素标记
                   <<qPrintable(e.attribute("id"));//id属性的值

            QDomNodeList list=e.childNodes();//获取e的全部子节点

            for(int i=0;i<list.count();i++)//遍历列表
            {
                QDomNode node=list.at(i);
                if(node.isElement())
                {
                    qDebug()<<"   "<<qPrintable(node.toElement().tagName())//输出元素名
                           <<qPrintable(node.toElement().text());//输出内容
                }
            }
        }
        n=n.nextSibling();//转到下一个兄弟节点

    }

 创建一个XML文件并添加内容:

构建思路:

 代码:

    QDomDocument doc;//创建一个Dom对象
    QDomProcessingInstruction instruction;//XML说明
    instruction=doc.createProcessingInstruction
            ("xml","version=\"1.0\" encoding=\"UTF-8\"");//创建XML说明
    doc.appendChild(instruction);//添加XML说明

    //创建根元素
    QDomElement root=doc.createElement("学生信息");
    doc.appendChild(root);//添加根元素
    //创建学生信息
    QDomElement id=doc.createElement("学号");
    QDomAttr number=doc.createAttribute("学号");//属性
    QDomElement name=doc.createElement("姓名");
    QDomElement age=doc.createElement("年龄");
    QDomElement height=doc.createElement("身高");
    QDomElement weight=doc.createElement("体重");
    QDomText text;//内容

    number.setValue(QString("1"));//设置学号的值
    id.setAttributeNode(number);//id元素中添加number属性

    //添加学生信息
    text=doc.createTextNode("王一");
    name.appendChild(text);
    text=doc.createTextNode("15");
    age.appendChild(text);
    text=doc.createTextNode("160");
    height.appendChild(text);
    text=doc.createTextNode("40");
    weight.appendChild(text);

    //把这些信息添加到id元素中
    id.appendChild(name);
    id.appendChild(age);
    id.appendChild(height);
    id.appendChild(weight);

    //将id添加到根元素中
    root.appendChild(id);

    //第二个学生
    id=doc.createElement("学号");
    number=doc.createAttribute("学号");//属性
    name=doc.createElement("姓名");
    age=doc.createElement("年龄");
    height=doc.createElement("身高");
    weight=doc.createElement("体重");

    number.setValue(QString("2"));//设置学号
    id.setAttributeNode(number);//id元素中设置number属性

    //添加信息
    text=doc.createTextNode("张三");
    name.appendChild(text);
    text=doc.createTextNode("16");
    age.appendChild(text);
    text=doc.createTextNode("165");
    height.appendChild(text);
    text=doc.createTextNode("45");
    weight.appendChild(text);

    //把这些信息添加到学号中
    id.appendChild(name);
    id.appendChild(age);
    id.appendChild(height);
    id.appendChild(weight);

    //将id添加到根元素中
    root.appendChild(id);

    QFile file("my.xml");
    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))return;
    QTextStream out(&file);
    doc.save(out,4);//保存到out中,4格缩进
    file.close();

打开该文件:

查找、修改、删除操作:

 

void Widget::find_updata_delete(const QString S)//
{
    QFile file("my.xml");//打开该文件
    if(!file.open(QFile::ReadOnly))
    {
        return;//打开失败的话退出
    }
    QDomDocument doc;
    if(!doc.setContent(&file))//获取数据失败
    {
        file.close();
        return;
    }
    //获取成功的话
    QDomNodeList list=doc.elementsByTagName("学号");//获取标签
    for(int i=0;i<list.count();i++)//遍历这些标签
    {
        QDomElement e=list.at(i).toElement();//获取元素
        if(e.attribute("学号")==ui->lineEdit->text())//如果匹配成功的话
        {
            if(S=="delete")//删除操作的话
            {
                QDomElement root=doc.documentElement();//获取根节点
                root.removeChild(list.at(i));//根节点中删除
                QFile file("my.xml");
                if(file.open(QIODevice::WriteOnly|QIODevice::Truncate))
                    return;
                QTextStream out(&file);
                doc.save(out,4);//保存到文件中
                file.close();//关闭文件
            }
            else if(S=="updata")
            {
                QDomNodeList child=list.at(i).childNodes();//获取当前节点所有的子节点
                child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_2->text());//更新姓名
                child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_3->text());//更新年龄
                child.at(2).toElement().firstChild().setNodeValue(ui->lineEdit_4->text());//更新身高
                child.at(3).toElement().firstChild().setNodeValue(ui->lineEdit_5->text());//更新体重
                QFile file("my.xml");
                if(file.open(QIODevice::WriteOnly|QIODevice::Truncate))
                    return;
                QTextStream out(&file);
                doc.save(out,4);//保存到文件中
                file.close();//关闭文件
            }
            else if(S=="find")
            {
                qDebug()<<e.tagName()<<" "<<e.attribute("学号");//输出元素名和学号
                QDomNodeList nodeList=e.childNodes();//获取内容节点
                for(int i=0;i<nodeList.count();i++)
                {
                    QDomNode node=nodeList.at(i);
                    if(node.isElement())
                    {
                        qDebug()<<node.toElement().tagName()<<" "<<node.toElement().text();//输出元素名和内容
                    }
                }
            }

        }

    }
}
void Widget::on_pushButton_clicked()//查找
{
    find_updata_delete("find");
}

 运行结果:

以上是Dom简单使用xml的方法。(感觉有点繁琐)

XML流

从Qt 4.3开始引入两个新类来读取和写入XML文档:

QXmlStreamReader类:

  • 是一个快速的解析器,使用简单的流API来读取格式良好的XML文档
  • QXmlStreamReader可以从QIODevice或QByteArray中读取数据
  • 流读取器:将XML文档报告为一个记号流,使用程序代码自身来驱动循环,在需要的时候可以从读取器中一个接着一个地拉出记号,使用readNext()函数获取记号

 QXmlStreamReader::TokenType:

常量描述
QXmlStreamReader::NoToken没有读过任何东西。
QXmlStreamReader::Invalid使用error()和errorString()中报告错误
QXmlStreamReader::StartDocument在documentVersion()中报告XML版本号,使用documentEncoding()中指定文档的编码
QXmlStreamReader::EndDocument报告文档结束
QXmlStreamReader::StartElement使用namespaceUri()和name()来报告元素开始,可以使用attributes()来获取属性
QXmlStreamReader::EndElement使用nameSpaceUri()和name()来报告元素结束
QXmlStreamReader::Characters使用text()来报告字符,如果字符是空白,那么isWhitespace()返回true,如果字符源于CDATA部分,那么isCDATA()返回true
QXmlStreamReader::Comment使用在text()中报告注释
QXmlStreamReader::DTD使用在 text() 中报告 DTD,在 notationDeclDeclarations() 中报告表示法声明,在 entityDeclarations() 中报告实体声明。DTD 声明的详细信息在 dtdName()、dtdPublicid和dtdSystemid() 中报告
QXmlStreamReader::EntityReference报告无法解析的实体引用。引用的名称在 name() 中报告,替换文本在 text() 中报告。
QXmlStreamReader::ProcessingInstruction使用processingInstruction Target()和processingInstruction Data()中报告处理指令

使用QXmlStreamReader读取xml文档:

具体流程:

  1. 先打开文件  file
  2. 创建一个阅读器,使用setDevice()设置读取对象
  3. 使用readNext()读取一个记号
  4. 使用读取的记号进行判断
#include <QApplication>
#include<QXmlStreamReader>
#include<QFile>
#include<QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFile file(":/new/xml/my.xml");
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
       return 0;
    }
    QXmlStreamReader reader;//创建一个阅读器
    reader.setDevice(&file);//设置需要读取的文件
    while(!reader.atEnd())//如果不到结尾
    {
        QXmlStreamReader::TokenType type=reader.readNext();//获取一个记号
        if(type==QXmlStreamReader::StartDocument)//读取XML说明
        {
            qDebug()<<reader.documentVersion()<<"  "<<reader.documentEncoding();//读取版本号和编码类型
        }
        if(type==QXmlStreamReader::StartElement)//获取元素
        {
            qDebug()<<reader.name();//获取元素名
            if(reader.attributes().hasAttribute("id"))//如果有属性
            {
                qDebug()<<reader.attributes().value("id");//输出属性
            }
        }
        if(type==QXmlStreamReader::EndElement)//获取结束元素
        {
            qDebug()<<reader.name();
        }
        if(type==QXmlStreamReader::Characters&&!reader.isWhitespace())
        {
            qDebug()<<reader.text();//读取内容
        }
    }
    if(reader.hasError())
    {
        qDebug()<<"error:"<<reader.errorString();
    }
    file.close();//关闭文件

    return a.exec();
}

 QXMLStreamWriter

用于编写XML文档

常用函数:

setAutoFormatting()设置自动化类型
hasError()写入失败返回true
setCodec()设置解码器,默认使用UTF-8
setDevice()设置写入的设备
writeTextElement()写入带有内容的元素
writeStartElement()写入起始元素
writeStartDocument()写入XML版本号和编码信息
writeProcessingInstruction()编写包含目标和数据 XML 处理指令
writeNamespace()为带有前缀命名空间 Uri 编写命名空间声明
writeEndElement()关闭上一个开始元素
writeEndDocument()关闭所有剩余的打开开始元素并写入换行符
writeEmptyElement()写入一个带有名称的空元素
writeDTD()写入 DTD 节
writeAttributes()写入属性

例子: 

    QFile file("Myxml.xml");
    if(!file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        return 0;
    }
    QXmlStreamWriter Writer;
    Writer.setDevice(&file);//获取流
    Writer.setAutoFormatting(true);
    Writer.writeStartDocument();//添加XML说明(版本号和编码信息
    Writer.writeStartElement("student");//写入起始元素
    Writer.writeStartElement("id");
    Writer.writeAttribute("id","1");//写入属性
    Writer.writeTextElement("name","王维");
    Writer.writeTextElement("age","15");
    Writer.writeTextElement("height","165");
    Writer.writeTextElement("weight","50");
    Writer.writeEndElement();//结束id元素编辑
    Writer.writeEndElement();//结束student元素编辑
    Writer.writeEndDocument();//结束整个的编辑
    file.close();//关闭文件

 

参考文档: 

XML 的用途 (w3school.com.cn)

XML Processing | Qt XML 5.15.12

  • 4
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习在Qt处理XML文件可以按照以下步骤进行: 1. 了解XML基础知识:学习XML的基本概念、语法和结构,了解XML的用途和优势。掌握XML的标签、元素、属性和命名空间等基本概念。 2. 学习QtXML模块:Qt提供了Qt XML模块,用于处理XML文件。学习Qt XML模块的相关类和函数,包括QDomDocument、QDomElement、QDomNode等。 3. 解析XML文件:学习使用Qt XML模块解析XML文件。可以使用QDomDocument类来读取和解析XML文件,获取XML文档的根节点,并通过遍历节点和获取节点属性等方式来访问XML文件的数据。 4. 创建和编辑XML文件:学习使用Qt XML模块创建和编辑XML文件。可以使用QDomDocument类创建一个新的XML文档,并使用QDomElement和QDomNode等类来创建元素、属性和子节点,然后将其保存为XML文件。 5. 数据操作:学习如何在Qt处理XML文件的数据。可以使用Qt提供的API来读取、修改和删除XML文件的数据,包括添加子节点、修改属性值、删除节点等操作。 6. 错误处理:学习如何处理XML文件解析过程可能出现的错误。Qt提供了错误处理机制,可以捕获和处理解析XML文件时可能出现的错误,如XML语法错误、节点不存在等。 7. 实践项目:通过实践项目来巩固所学知识。可以尝试编写一个简单的程序,使用Qt XML模块读取和解析XML文件,并对文件的数据进行操作和展示。 此外,Qt官方文档提供了详细的XML模块的使用说明和示例代码,可以参考官方文档来学习和理解更多关于在Qt处理XML文件的知识。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值