xml 文档内容结构
1.预处理指令(Processing instructions)
作用:指示XML解析器(XML API)如何处理XML文件,只能插入在XML文档的第一行
eg: <?xml version="1.0" encoding="UTF-8"?>
处理指令的起始:<?
处理指令的结束:?>
- version="1.0" 用于指定XML版本,至今一直是1.0
- encoding="UTF-8" 是指XML文本编码方式,建议使用UTF-8,建议不要改变任何字符,原封不动的写
2.标签(tag)
eg: <books></books>
<books>:起始标签(区分大小写),</books>:结束标签(区分大小写),其中起始标签和结束标签成对出现
标签的嵌套,如下:有且仅有一个根标签,根标签下允许多个字标签嵌套
<books>
<book>
<name></name>
<author></author>
</book>
</books>
命名规则
- 不能以数字或“_”(下划线)开头
- 不能以xml(或XML、或Xml等)开头
- 不能包含空格
- 名称中间不能包含冒号(:)
- 区分大小写,eg:<books></Books>是错误的
3.注释(comment)
<!--注释内容-->
<books>
<book>
<!--
<name></name>
<author></author>
-->
</book>
</books>
4.属性(attribute)
在开始标签上定义属性,属性名=“属性值”(等号前后不能加空格,且单双引号均可)
<books>
<book id="1" price="12.0">
<name></name>
<author></author>
</book>
<book id="2" price="13.0">
<name></name>
<author></author>
</book>
</books>
属性名可以任意扩展,不能重复
属性值可任意扩展,必须使用引号(单双引号均可)
在开始标签中可定义多个属性,属性没有顺序
命名规则:
同标签的命名规则
5.内容
<books>
<book id="1" price="12.0">
<name>Brief History of Time</name>
<author>Hawking</author>
</book>
<book id="2" price="13.0">
<name>Linux OS</name>
<author>Linux</author>
</book>
</books>
文本内容:<name>Brief History of Time</name>,中的Brief History of Time
子标签:eg:<books>...</books>之间的<book>...</book>
子标签和文本混合:eg: <book>...</book>两个标签之间包含<name>Brief History of Time</name>
6.元素
构成:<起始标签>内容</结束标签>三部分组成
xml 文档写入(Qt实现)
写入方式:在内存中以DOM树的结构表示数据,并将这个树形结构写入文件中
定义用于内存数据存储的数据结构
#include <QWidget>
namespace Ui {
class Widget;
}
//内存数据结构定义如下
struct sBooks
{
int id; //书的索引id
float price; //书的单价
QString name; //书的名称
QString author; //书的作者
sBooks() //构造函数
{
id = -1;
price = 0.0;
name = "";
author = "";
}
bool operator==(sBooks& books)//"=="操作符定义
{
return (id == books.id);
}
};
Q_DECLARE_METATYPE(sBooks) //可通过QVariant 转化
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public:
void readXML(char* filePath,QList<sBooks>& books);
void writeXML(char* filePath,QList<sBooks>& books);
private:
void assignmentValue();//测试时,自定义赋值
private:
Ui::Widget *ui;
QList<sBooks> m_data;
};
将数据结构中的内存数据写入到文件中
void Widget::assignmentValue()
{
sBooks books1;
books1.id = 1;
books1.price = 12.0;
books1.name = "Brief History of Time";
books1.author = "Hawking";
sBooks books2;
books2.id = 3;
books2.price = 13.0;
books2.name = "Linux OS";
books2.author = "Linux";
m_data.append(books1);
m_data.append(books2);
}
void Widget::writeXML(char* filePath,QList<sBooks>& sbooks)
{
QDomDocument doc("MyXML");
//create processing instruction
QDomProcessingInstruction processIns = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(processIns);
//create root node
QDomElement root = doc.createElement("books");
doc.appendChild(root);
//create "book" sub node
for (int i=0; i<sbooks.size(); i++)
{
sBooks books = sbooks.at(i);
QDomElement book = doc.createElement("book");
book.setAttribute("id",QString::number(books.id) );
book.setAttribute("price",QString::number(books.price));
root.appendChild(book);
//create "name" sub node of book
QDomElement name = doc.createElement("name");
//create "name" node content
QDomText t = doc.createTextNode(books.name);
name.appendChild(t);
book.appendChild(name);
//create "author" sub node of book
QDomElement author = doc.createElement("author");
QDomText strAuthor = doc.createTextNode(books.author);
author.appendChild(strAuthor);
book.appendChild(author);
}
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this,"QIodevice Error","open file failed",QMessageBox::Ok);
return;
}
QTextStream out(&file);
doc.save(out,4);
}
xml 文档读取(Qt实现)
读取方式:利用DOM(文档对象模型)把XML文档转换为应用程序可以遍历的树形结构
void Widget::readXML(char* filePath,QList<sBooks>& books)
{
QDomDocument doc("myDomDocument");
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
return;
if (!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomElement root = doc.documentElement();
for (int i=0; i<root.childNodes().size(); i++)
{
sBooks book;
QDomNode node = root.childNodes().at(i);
QDomElement ele = node.toElement();
book.id = ele.attribute("id").toInt();
book.price = ele.attribute("price").toFloat();
for (int j=0; j<ele.childNodes().size(); j++)
{
QDomNode subNode = ele.childNodes().at(j);
QDomElement subEle = subNode.toElement();
if (subEle.tagName() == "name")
book.name = subEle.text();
if (subEle.tagName() == "author")
book.author = subEle.text();
}
m_data.append(book);
}
}