XML
什么事XML文件
XML,可扩展标记语言(Extensible Markup Language),是一种标记语言。一般用 于数据存储、配置文件存储,(Qt的ui文件就是xml)也可以跨平台跨语言进行数据传输
XML作用
- 丰富文件(Rich Documents)-自定文件描述并使其更丰富;
- 属于文件为主的XML技术应用;
- 标记是用来定义一块数据应该如何呈现;
- 解释数据(Metadata)-描述其它文件或在线信息;
- 属于数据为主的XML技术应用;
- 标记是用来说明一块资料的意义;
- 组态档案(Configuration Files)-描述软件的组态参数
XML语法规则
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
- XML声明
一个xml文档必须要有第一行的声明和它的文档元素的描述信息。
例子:
注:xml声明一般是xml文档的第一行;xml声明由以下几个部分组成:
- 所有的 XML 元素都必须有一个关闭标签
- XML 标签对大小写敏感
- XML 文档必须有根元素
- XML 必须正确嵌套
- XML 属性值必须加引号
实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:<message>if salary < 1000 then</message>
为了避免这个错误,请用实体引用来代替 “<” 字符:<message>if salary < 1000 then</message>
- 在 XML 中,有 5 个预定义的实体引用:
< | < | less than |
---|---|---|
> | > | greater than |
& | & | ampersand |
' | ’ | apostrophe |
" | " | quotation mark |
PS:在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯
XML中的注释
在 XML 中编写注释的语法与 HTML 的语法很相似。
! 注意注释不能写在标签的最上面
<!-- This is a comment -->
在 XML 中,空格会被保留
XML 以 LF 存储换行
-
在 Windows 应用程序中,换行通常以一对字符来存储:回车符(CR)和换行符(LF)。
-
在 Unix 和 Mac OSX 中,使用 LF 来存储新行。
-
在旧的 Mac 系统中,使用 CR 来存储新行。
-
XML 以 LF 存储换行。
以上就是在使用 XML 时需要注意到的语法规则,按照这些规则,编写一个正确的 XML 文档!
Qt 操作XML文件
- QXmlStreamWriter
- QXmlStreamReader
XML读操作
QXmlStreamReader xml;
...
while (!xml.atEnd()) {
xml.readNext();
... // do processing
}
if (xml.hasError()) {
... // do error handling
}
XML写操作
#include <QCoreApplication>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QTextCodec>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("./writeFile.xml");
file.open(QFile::WriteOnly | QFile::Truncate);
QXmlStreamWriter stream(&file);
stream.setCodec(QTextCodec::codecForName("utf-8"));
stream.setAutoFormatting(true); //排版格式
stream.writeStartDocument();
stream.writeStartElement("teachers");
/*老王*/
stream.writeStartElement("teacher");
stream.writeAttribute("id", "01");
stream.writeAttribute("time", "23:30"); //子时 练习
stream.writeTextElement("name", QString::fromLocal8Bit("老王"));
stream.writeTextElement("book", QString::fromLocal8Bit("葵花宝典"));
stream.writeEndElement();
/* robort */
stream.writeStartElement("teacher");
stream.writeAttribute("id", "02");
stream.writeAttribute("time", "04:00");
stream.writeTextElement("name", "robort");
stream.writeTextElement("book", QString::fromLocal8Bit("金瓶梅"));
stream.writeEndElement();
/* 夏七 */
stream.writeStartElement("teacher");
stream.writeAttribute("id", "03");
stream.writeAttribute("time", "19:00");
stream.writeTextElement("name", QString::fromLocal8Bit("夏七"));
stream.writeTextElement("book", QString::fromLocal8Bit("红楼梦"));
stream.writeEndElement();
stream.writeEndElement();
stream.writeEndDocument();
file.close();
return a.exec();
}
使用读写流操作XML
#include <QCoreApplication>
#include <QFile>
#include <QXmlStreamReader>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("./test.xml");
if (!file.open(QFile::ReadOnly | QFile::Text))
{
qDebug()<<"Error: cannot open file";
return 0;
}
QXmlStreamReader reader;
// 设置文件,这时会将流设置为初始状态
reader.setDevice(&file);
// 如果没有读到文档结尾,而且没有出现错误
while (!reader.atEnd())
{
// 读取下一个记号,它返回记号的类型
QXmlStreamReader::TokenType type = reader.readNext();
// 下面便根据记号的类型来进行不同的输出
if (type == QXmlStreamReader::StartDocument)
qDebug() << reader.documentEncoding() << reader.documentVersion();
if (type == QXmlStreamReader::StartElement) {
qDebug() << "<" << reader.name() << ">";
if ((reader.attributes().hasAttribute("id"))&& (reader.attributes().hasAttribute("time")))
qDebug() << reader.attributes().value("id")<<" " <<reader.attributes().value("time");
}
if (type == QXmlStreamReader::EndElement)
qDebug() << "</" << reader.name() << ">";
if (type == QXmlStreamReader::Characters && !reader.isWhitespace())
qDebug() << reader.text();
//listwidget‐>additem;
}
// 如果读取过程中出现错误,那么输出错误信息
if (reader.hasError()) {
qDebug() << "error: " << reader.errorString();
}
file.close();
return a.exec();
}