Qt读写xml格式字符串

转自:https://blog.youkuaiyun.com/lovebird_27/article/details/50205995

Xml 简介

W3CXML教程
XML是ExtensibleMarkup Language的缩写,即可扩展标记语言。它是一种用来创建的标记的标记语言。使用XML标记语言可以做到数据或数据结构在任何编程语言环境下的共享。
XML 被设计用来传输和存储数据
HTML 被设计用来显示数据。
XML解析器是读取XML文档并提供对文档内容的访问的软件模块

Qt 读取 XML 文档的方法

A QXmlStreamReader:一种快速的基于流的方式访问良格式 XML 文档,特别适合于实现一次解析器(所谓“一次解析器”,可以理解成我们只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会有反复的情况,也就是不会读完第一个标签,然后读第二个,读完第二个又返回去读第一个,这是不允许的);这种方法是通过调用readNext()函数实现的,可以读取下一个记号,然后返回一个记号类型。
B DOM(Document Object Model):将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航,这是与另外两种方式最大的区别,也就是允许实现多次解析器(对应于前面所说的一次解析器)。DOM 方式带来的问题是需要一次性将整个 XML 文档读入内存,因此会占用很大内存;
C SAX(Simple API for XML):提供大量虚函数,以事件的形式处理 XML 文档。应用程序必须提供处理器(回调函数) 来从解析器获得所谓XML事件。

Qt生成 XML 文档方法

A QXmlStreamWriter与QXmlStreamReader相对应。XML流的方法
B DOM 方式,首先在内存中生成 DOM 树,然后将 DOM 树写入文件。
C 纯手工生成 XML 文档。

Qt中DOM的使用
//xml中的XML说明对应QDomProcessingInstruction

//xml中的元素对应QDomElement类

//xml中的属性对应QDomArr类

//xml中的文本内容对应QDomText类

//Qt中,所有的Dom节点,比如说明,元素,属性和文本等,都使用QDomNode来表示

//文档本身用 QDomDocument 类表示

//访问XML文件

    // 新建QDomDocument类对象,它代表一个XML文档

    QDomDocument doc;


    // 定义一个文件对象

    QFile file("../myDOM1/my.xml");

    //setContent()函数设置整个文档内容,将xml文档内容解析为一个DOM树

    doc.setContent(&file);  


    // 获得doc的第一个结点,即XML说明

    QDomNode firstNode = doc.firstChild();  //若换为lastChild() 指的是根元素


    // 返回根元素

    QDomElement docElem = doc.documentElement();

    // 返回根节点的第一个子结点

    QDomNode n = docElem.firstChild();  //lastChild()获取最后一个节点  输出的是book03


    // 转到下一个兄弟结点

    n = n.nextSibling();  //使用previousSibling访问前一个节点

//创建XML文件

    // 添加处理指令即XML说明

    QDomProcessingInstruction instruction;

    instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");

    doc.appendChild(instruction);  //添加在最后

    // 添加元素

    QDomElement book = doc.createElement(QString("图书"));



    // 添加属性及其值

    QDomAttr id = doc.createAttribute(QString("编号"));

    id.setValue(QString("1"));

    book.setAttributeNode(id);

    //文本及其文本值

    QDomText text;

    text = doc.createTextNode(QString("Qt"));

Qt中SAX的使用

SAX(simple API for XML)为XML解析器提供了一个基于事件的标准接口。在Qt中支持SAX2不支持java中的SAX1

Qt中XML流的使用

Qt中用了两个类来读取和写入XML文档( QXmlStreamWriter与QXmlStreamReader),前面讲到过在读取XML文档时是通过readNext()函数获取下一个记号,返回的是记号
类型,它由 QXmlStreamReader::TokenType 定义,具体记号类型如图:

//QXmlStreamReader 解析文档

    QFile file("../myXmlStream/my.xml");

    QXmlStreamReader reader;

    // 设置文件,这时会将流设置为初始状态

    reader.setDevice(&file);

    while (!reader.atEnd()) {

        // 读取下一个记号,它返回记号的类型

        QXmlStreamReader::TokenType type = reader.readNext();  //所有取值表17-6 P417

        // 下面便根据记号的类型来进行不同的输出

        if (type == QXmlStreamReader::StartDocument)



        if (type == QXmlStreamReader::StartElement) { //元素的起始



            if (reader.attributes().hasAttribute("id"))//如果有属性为ID的元素



        }

        if (type == QXmlStreamReader::EndElement)   //元素的截止



        if (type == QXmlStreamReader::Characters && !reader.isWhitespace()) //文本内容



    }

//QXmlStreamWriter 创建文档

    QFile file("../myXmlStream/my2.xml");

    QXmlStreamWriter stream(&file);

    //设置自动格式,会自动换行和添加缩进

    stream.setAutoFormatting(true);

    //自动添加首行的XML说明<?xml version="1.0" encoding="UTF-8"?>

    stream.writeStartDocument();

    //添加元素

    stream.writeStartElement("book"); //起始元素

    stream.writeAttribute("href", "http://qt.nokia.com/");

    stream.writeTextElement("title", "Qt Home"); //文本元素   使用这个关闭前一个打开的元素    

    stream.writeEndElement();

    stream.writeEndDocument();
<think>我们想要读取一个SVG文件的内容为字符串,以便用于设置QPushButton的图标(通过SVG字符串而不是文件路径)在Qt中,我们可以使用QFile和QTextStream来读取文件内容为QString。注意:由于SVG文件是文本文件(XML格式),我们可以直接以文本方式读取。示例代码:假设我们有一个SVG文件路径,我们将读取其内容到一个QString对象中。然后,我们可以使用之前的方法(通过QSvgRenderer等)将这个SVG字符串设置为按钮的图标。步骤:1.使用QFile打开文件。2.使用QTextStream读取文件内容到字符串。3.关闭文件。4.使用读取到的字符串创建图标(如之前所述)。注意:需要包含头文件<QFile>,<QTextStream>。下面是一个读取文件内容为字符串的函数:```#include<QFile>#include<QTextStream>QStringreadFileToString(constQString&filePath){QFilefile(filePath);if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){qWarning()<<"Couldnotopenfile:"<<filePath;returnQString();}QTextStreamin(&file);in.setCodec("UTF-8");//设置编码,SVG文件通常使用UTF-8QStringcontent=in.readAll();file.close();returncontent;}```使用示例:```QStringsvgContent=readFileToString(":/icons/icon.svg");if(!svgContent.isEmpty()){//使用之前的方法将svgContent设置为按钮的图标setSvgIcon(button,svgContent,QSize(32,32),QColor("red"));}```注意:如果文件是在Qt资源系统中(以冒号开头的路径,如":/icons/icon.svg"),同样适用。另外,如果文件很大,使用readAll()可能不是最佳选择,但SVG文件通常不大,所以可以接受。如果需要处理大文件,应该考虑逐块读取并追加到字符串,但这里我们不需要。现在,结合之前设置SVG图标的方法,我们可以实现从文件读取SVG内容并设置为按钮图标,而不需要直接使用文件路径。这样做的优点:我们可以动态修改SVG字符串(例如改变颜色等)然后再渲染。相关问题:1.如何读取二进制文件(如图片)为QByteArray?2.Qt中如何设置不同状态(如悬停、按下)的按钮SVG图标?3.如何将修改后的SVG字符串保存回文件?4.在Qt资源系统中,如何列出所有文件?5.如何处理不同编码的文本文件?</think>### 在 Qt 中将文件内容读取为字符串的完整指南 在 Qt 中读取文件内容为字符串是常见操作,尤其适用于将 SVG 文件内容读取为字符串后用于设置 `QPushButton` 的图标。以下是两种主要方法: #### 方法 1: 使用 QFile 和 QTextStream(推荐) ```cpp #include <QFile> #include <QTextStream> QString readFileToString(const QString& filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "无法打开文件:" << filePath; return QString(); } QTextStream in(&file); in.setCodec("UTF-8"); // 设置编码确保正确处理中文 QString content = in.readAll(); file.close(); return content; } // 使用示例 QString svgContent = readFileToString(":/icons/button.svg"); if (!svgContent.isEmpty()) { // 使用之前介绍的setSvgIcon方法 setSvgIcon(ui->pushButton, svgContent, QSize(32, 32)); } ``` #### 方法 2: 使用 QFile 和 readAll() ```cpp #include <QFile> QString readFileToString(const QString& filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { return QString(); } QByteArray byteArray = file.readAll(); file.close(); return QString::fromUtf8(byteArray); // 转换为QString } ``` #### 关键点说明: 1. **文件路径处理**: - 资源文件使用 `":/prefix/filename.ext"` 格式[^3] - 绝对路径:`"/path/to/file"` - 相对路径:`"subfolder/file.ext"` 2. **编码处理**: ```cpp // 自动检测编码 QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); // 手动指定编码 QTextStream in(&file); in.setCodec("UTF-8"); ``` 3. **错误处理增强**: ```cpp if (!file.exists()) { qCritical() << "文件不存在:" << filePath; return QString(); } if (file.size() > 10 * 1024 * 1024) { // 10MB限制 qWarning() << "文件过大,跳过读取"; return QString(); } ``` 4. **读取资源文件中的SVG**: ```cpp // 使用Qt资源系统 QFile svgFile(":/ui_assets/button_icon.svg"); svgFile.open(QIODevice::ReadOnly); QString svgData = QString::fromUtf8(svgFile.readAll()); ``` #### 完整工作流程: ```mermaid graph TD A[启动应用程序] --> B[获取文件路径] B --> C{路径类型} C -->|资源文件| D[使用 :/ 前缀] C -->|本地文件| E[使用绝对/相对路径] D --> F[QFile打开文件] E --> F F --> G{打开成功?} G -->|是| H[读取全部内容] G -->|否| I[错误处理] H --> J[转换为QString] J --> K[设置按钮SVG图标] ``` #### 性能优化技巧: 1. **缓存机制**: ```cpp static QCache<QString, QString> fileCache(10 * 1024 * 1024); // 10MB缓存 if (fileCache.contains(filePath)) { return *fileCache.object(filePath); } else { QString* content = new QString(readFile(filePath)); fileCache.insert(filePath, content); return *content; } ``` 2. **异步读取**: ```cpp QtConcurrent::run([=](){ QString content = readFileToString(filePath); QMetaObject::invokeMethod(this, [=](){ setSvgIcon(button, content, iconSize); }); }); ``` #### 常见问题解决: 1. **中文路径问题**: ```cpp QString path = QString::fromLocal8Bit("D:/中文路径/图标.svg"); ``` 2. **跨平台路径处理**: ```cpp QString path = QDir::toNativeSeparators("C:/icons/button.svg"); ``` 3. **资源文件刷新**: - 修改资源文件后需重新运行 `qmake` 和 `make` --- ### 相关问题 1. 如何在 Qt 中安全地写入字符串内容到文件? 2. Qt 资源系统(.qrc)的工作原理是什么?如何管理大型资源文件? 3. 如何处理不同编码(GBK, BIG5, Shift-JIS)的文本文件? 4. Qt 中异步文件读写的最佳实践是什么? 5. 如何实现文件变更监控(如 SVG 文件修改后自动更新图标)?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值