基于Qt命令行处理XML文件读写

XML 系列教程

"当 XML(扩展标记语言)于 1998 年 2 月被引入软件工业界时,它给整个行业带来了一场风暴。有史以来第一次,这个世界拥有了一种用来结构化文档和数据的通用且适应性强的格式,它不仅仅可以用于 WEB,而且可以被用于任何地方。"

---《Designing With Web Standards Second Edition》, Jeffrey Zeldman

XML

XML 指可扩展标记语言

XML 被设计用来传输和存储数据。

XML 实例

这些例子演示了 XML 文件、XML 格式化和 XML 转换(XSLT)。

还演示了与 XML 一起使用的 JavaScript (AJAX)。

查看一个简单的 XML 文件

xml 复制代码
<note>

<to>George</to>

<from>John</from>

<heading>Reminder</heading>

<body>Don't forget the meeting!</body>

</note>

XML 简介

XML 被设计用来传输和存储数据。
HTML 被设计用来显示数据。

应该掌握的基础知识:

在您继续学习之前,需要对以下知识有基本的了解:

  • HTML / XHTML
  • JavaScript## 应该掌握的基础知识:

在您继续学习之前,需要对以下知识有基本的了解:

  • HTML / XHTML
  • JavaScript

什么是 XML?

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

XML 与 HTML 的主要差异

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

XML 被设计为传输和存储数据,其焦点是数据的内容。

HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

没有任何行为的 XML

XML 是不作为的。

也许这有点难以理解,但是 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。

下面是 John 写给 George 的便签,存储为 XML:

xml 复制代码
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

上面的这条便签具有自我描述性。它拥有标题以及留言,同时包含了发送者和接受者的信息。

但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。

通过 XML 您可以发明自己的标签

上例中的标签没有在任何 XML 标准中定义过。这些标签是由文档的创作者发明的。

这是因为 XML 没有预定义的标签。

XML 允许创作者定义自己的标签和自己的文档结构。

XML 不是对 HTML 的替代

XML 是对 HTML 的补充

XML 不会替代 HTML,理解这一点很重要。在大多数 web 应用程序中,XML 用于传输数据,而 HTML 用于格式化并显示数据。

对 XML 最好的描述是:

XML 是独立于软件和硬件的信息传输工具。

XML 无所不在

目前,XML 在 Web 中起到的作用不会亚于一直作为 Web 基石的 HTML。

XML 无所不在。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。


Qt源码在后面,文本介绍Qt国际化语言和XML

XML作用(能用来干啥?)

  • (1)作为数据传输的标准。好读,好维护,好扩展,与编程语言无关,任谁都会选择他来担任这个数据传输的角色吧。。。
  • (2)作为配置文件。其实很多软件和框架,都会提供XML文件配置的方式,以便可以方便快捷的修改软件或框架的功能。
  • (3)持久化数据。啥意思?简单来说就是可以将数据存到xml文件中,把xml当做一个临时的小型数据库。当然,重要的数据还是要存到正经的数据库中的,别问为什么,问就是xml存数据会不安全(doge)。
  • (4)简化平台变更。在系统更换平台的时候,普通的数据会存在不兼容的问题,但是XML 数据以文本格式存储,使得 XML 在不损失数据的情况下,更容易扩展和升级。简直不要太好用。

4、XML和CSS

CSS简介

XML文件中的内容,可以配合CSS进行内容的样式渲染,例如控制字体大小、颜色等。

CSS(Cascading Style Sheets) 层叠样式表,通常用来给HTML中内容、或者XML中内容进行样式的渲染

例如:先创建一个css后缀的文件,在该文件中编写下面的代码

css 复制代码
name{  font-size:30px;  font-weight:bold;  color:red;}name{  font-size:30px;  font-weight:bold;  color:green;}​
处理指令

处理指令,简称PI (processing instruction),可以用来指定解析器如何解析XML文档内容。

例如:在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,使用test.css文件来渲染xml内容。

xml 复制代码
<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href="test.css" type="text/css"?> <class>  <student id="001">    <name>张三</name>    <age>20</age>  </student>  <student id="002">    <name>李四</name>    <age>20</age>  </student></class>​

渲染后的效果如下:


## 5、Qt XML


XML和Qt密不可分,还记得QT的.ui文件吗,就是XML文件

未来XML的用户使用量只增不减,所以有必要记录一下。

## 5.1 .pro文件

采用的是命令行项目,没有.ui文件的

c++ 复制代码
# 配置命令行cmdline
CONFIG   += cmdline
QT       -= gui
SOURCES  += main.cpp
​
# 【1】 如果项目很大 需要添加resources_big
CONFIG += resources_big
# 【2】国际化语言翻译文件绝对路径
TRANSLATIONS  +=  translation/tr_zh.ts  \
                  translation/tr_en.ts
# install
target.path = $$[QT_INSTALL_EXAMPLES]/xml/xmlstreamlint
INSTALLS += target
​

【2】是生成国际化语言的绝对路径,还需执行以下操作才能生成完整的多国翻译文件。

更新翻译:生成.ts文件

发布翻译:生成.qm文件

如果你想翻译多个国家的语言,就在对应的.ts文件修改即可

bash 复制代码
<translation type="unfinished">填写你翻译的文本</translation>
Qt国际化语言相对简单,但不是本节的重点,只是代码中有使用tr()函数,所以让大家了解一下。

## 5.2 main文件

文本项目内容不多,所以直接在main全部实现,主要是对XML文件进行读写。【从myxml.xml文件读取->写入savaXML.xml文件】

c++ 复制代码
/****************************************************************************
**
** WX公众号:Qt历险记
** CSDN博客网:Qt魔术师
**
****************************************************************************/
​
#include <QCoreApplication>
#include <QFile>
#include <QStringList>
#include <QTextStream>
#include <QXmlStreamReader>
​
/*
 此类的唯一目的是创建翻译上下文。【可以翻译成各个国家】
*/
class XmlStreamLint
{
public:
    // 从字面意思:声明tr函数 tr()函数就是用来处理国际化语言的 因为tr()时QObject的方法QObject::tr() or QObject::trUtf8(),而增加头文件会增加编译的时间
    // 这个宏的功能:XmlStreamLint可以调用以下两个函数
    /*  static inline QString tr(const char *sourceText,
                           const char *comment = 0);
        static inline QString trUtf8(const char *sourceText,
                               const char *comment = 0);
    */
    Q_DECLARE_TR_FUNCTIONS(XmlStreamLint) // 必须出现在类定义的最顶部
};
​
int main(int argc, char *argv[])
{
    enum ExitCode
    {
        Success,
        ParseFailure,
        ArgumentError,
        WriteError,
        FileFailure
    };
​
    // 打包发布时可以设置插件的目录 默认路径列表由一个条目组成,即插件的安装目录。
    // 由于Qt在构造QApplication时会加载插件,因此设置此项的机会就是在调用QApplication的构造函数之前进行
    QCoreApplication::addLibraryPath("pluins");
​
    QCoreApplication app(argc, argv);
​
    QTextStream errorStream(stderr); // 标准IO出错
​
    errorStream <<"argc = "<<argc<<Qt::endl;
    errorStream <<"arg0 = "<<QCoreApplication::arguments().at(0)
                <<Qt::endl<<"arg1 = "<<QCoreApplication::arguments().at(1)<<Qt::endl
                <<Qt::endl<<"arg2 = "<<QCoreApplication::arguments().at(2)<<Qt::endl; // 外部参数
​
    // 命令行参数个数可以在编译时指定:点击最左侧项目->点击Run按钮->在运行的下面第二行:mmand linearguments:行编辑框输入参数,参数之间空格分隔,注意一个完整的参数中不能有空格不然被分成了两个参数
    if (argc != 3)
    {
        errorStream << XmlStreamLint::tr(
                       "Usage: xmlstreamlint <path to XML file>\n");
        return ArgumentError;
    }
​
    // 参数arg0是默认应用程序编译生成的.exe文件的绝对路径,arg1才是我们输入的第一个命令行参数
    QString inputFilePath(QCoreApplication::arguments().at(1));
    QFile inputFile(inputFilePath);
​
    // 文件不存在
    if (!QFile::exists(inputFilePath))
    {
        errorStream << XmlStreamLint::tr(
                       "File %1 does not exist.\n").arg(inputFilePath);
        return FileFailure;
​
    }
    // 文件打开失败
    else if (!inputFile.open(QIODevice::ReadOnly)) {
        errorStream << XmlStreamLint::tr(
                       "Failed to open file %1.\n").arg(inputFilePath);
        return FileFailure;
    }
​
    // 写入我指定的另一个空的XML文件
    QString outFilePath(QCoreApplication::arguments().at(2));
    QFile outputFile(outFilePath);
    if (!outputFile.open(QIODevice::WriteOnly))
    {
        errorStream << XmlStreamLint::tr("Failed to open " + outputFile.fileName().toUtf8());
        return WriteError;
    }
​
//! [第一步]
//! // qxml流阅读器类提供了一个快速解析器,可以通过简单的流api读取格式良好的xml
    QXmlStreamReader reader(&inputFile);
    // qxml流媒体写入器类提供了一个具有简单流媒体api的xml写入器
    QXmlStreamWriter writer(&outputFile);
//! [end]
​
//! [第二步] 按行读取XML文件
    while (!reader.atEnd())
    {
        reader.readNext();
​
        if (reader.error()) // 解析错误 只是在那行那列
        {
            errorStream << XmlStreamLint::tr(
                           "Error: %1 in file %2 at line %3, column %4.\n").arg(
                               reader.errorString(), inputFilePath,
                               QString::number(reader.lineNumber()),
                               QString::number(reader.columnNumber()));
            return ParseFailure;
//! [end]
​
//! [第三步]
        }
        else {
            // 写入读者的当前状态。支持所有可能的有效状态。此函数的目的是支持对xml数据的链式处理。
            writer.writeCurrentToken(reader); // 读取的内容写入到文件中
        }
    }
//! [end]
​
    return Success;
}
​

## 5.3 运行步骤

需要先添加命令行参数,才能有效果哦,注意命令行参数之间使用空格分隔,也就是你的路径中最好不要有空格,不然就被理解成多个参数了。

点击:

文件如下:如何快速添加路径

方法1:右键属性,安全,对象名称就是绝对路径

方法2是对方法1的拓展:在Exporer中显示,其他操作如同方法1

命令行添加完毕,可以运行

运行成功

使用VScode打开两个文件看看:

==XML远远不止这些,下次继续肝==

相关推荐
虾球xz2 分钟前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇8 分钟前
HTML常用表格与标签
前端·html
疯狂的沙粒12 分钟前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员27 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐29 分钟前
前端图像处理(一)
前端
程序猿阿伟37 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒38 分钟前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪1 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背1 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript
程楠楠&M1 小时前
node.js第三方Express 框架
前端·javascript·node.js·express