xml常用知识总结

1. 总述
XML是一种类似于HTML的标记语言,但它的设计目的是用来传输数据,而不是显示数据。
XML的标签没有被预定义,用户需要在使用时自行进行定义。
相对于数据库表格的二维表示,XML使用的树形结构更能表现出数据的包含关系。
作为一种文本文件格式,XML简单明了的特性使得它在信息存储和描述领域非常流行。
    在Qt中提供了QtXml模块来进行XML文档的处理。
    我们在Qt帮助中输入关键字QtXml Module,可以看到该模块的类表。
    这里主要提供了三种解析方法: 
    DOM方法: 可以进行读写;
    SAX方法: 可以进行读取;
    基于流的方法:分别使用QXmlStreamReader和QXmlStreamWriter进行读取和写入。
    注1:要在项目中使用QtXml模块,还需要在项目文件(.pro文件)中添加 "QT += xml"  一行代码。
    注2: 在 Qt4 中,这三种方式都位于 QtXml 模块中。Qt5 则将 QXmlStreamReader/QXmlStreamWriter 移动到 QtCore 中


2. 标准的xml示例
<?xml version="1.0" encoding="UTF-8"?> //xml说明
<library>
<book id="01">
<title>Qt</title>
<author>shiming</author>
</book>
<book id="02">
<title>Linux</title>
<author>yafei</author>
</book>
</library>


1> xml说明:对XML文档处理的环境和要求的说明,encoding=“UTF-8”是使用的编码,
指出文档是使用何种字符集建立的,默认值为Unicode 编码
2> xml元素:一个元素由起始标签<标签名>和终止标签</标签名>以及两个标签之间的内容组成,
而文档中第一个元素被称为根元素,比如这里的<library></library>,
XML文档必须有且只有一个根元素 
3> 元素可以包含属性,用来描述元素的相关信息,属性名和属性值在元素的起始标签中给出,
格式为<元素名 属性名=“属性值”>,如<book id=“01”>,属性值必须在单引号或者双引号中。
4> 在元素中可以包含子元素,也可以只包含文本内容,比如这里的<title>Qt</title>中的Qt就是文本内容。


3. DOM方式
1> 在QDom中,是将整个XML文件读到内存中的doc对象中的。然后使用节点(QDomNode )操作doc对象,
像XML说明,元素,属性,文本等等都被看做是节点,这样就使得操作XML文档变得很简单,
我们只需通过转换函数将节点转换成相应的类型,如:QDomElement e =n.toElement();
2> 优点: 将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航,
这是与另外两种方式最大的区别,也就是允许实现多次解析器.
3> 缺点:DOM需要预先把整个XML文档都读入内存,这样就使得它不适合处理较大的文件。
4> 创建节点,将其写入XML文件,主要操作包括:
        1). 打开文件
            QFile file(filepath);//通过文件路径打开
            file.open(QIODevice::ReadWrite);//打开文件方式


        2). 添加xml第一行(xml文档说明)
            QDomDocument doc;
            QDomProcessingInstruction instruction;
            instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
            doc.appendChild(instruction);


        3). 创建根节点
            QDomElement root = doc.createElement("library");//添加根元素


        4). 创建其他节点
            QDomElement booknode = doc.createElement("book");
            QDomElement titlenode = doc.createElement("title");
            QDomElement authornode = doc.createElement("author");


        5). 创建节点属性
            //方式一:创建属性  其中键值对的值可以是各种类型
            booknode.setAttribute("id",01);
            //方式二:创建属性 值必须是字符串
            QDomAttr idattr=doc.createAttribute("id"); //创建key值
            idattr.setValue("2013/6/13");   //创建对应value值
            booknode.setAttributeNode(idattr);  //绑定对应到节点上


        6). 创建节点文本内容
            QDomText text;
            text = doc.createTextNode("Qt");
            titlenode.appendChild(text);            
            text.clear();


            text = doc.createTextNode("shiming");
            authornode.appendChild(text);
            text.clear();


        7). 将节点按照逻辑串起来
            booknode.appendChild(authornode);
            booknode.appendChild(titlenode);
            root.appendChild(booknode);
            doc.appendChild(root);//注意这一步,容易忽略


        8). 写入到文件中,保存关闭文件
            QTextStream out(&file);
            doc.save(out,4);//设置缩进为4个空格
            file.close();


创建一个便签节点后,若要继续添加便签节点,则需要在已有节点后增加一个新节点,并重写入XML文件。


5> 操作节点信息,主要操作包括:
        QDomDocument doc;
1).读取根节点:
            QDomElement root = doc.documentElement();
2).读取根节点的第一个子节点:
            QDomNode node = root.firstChild();
3).读取节点的下一个同级节点:
            node = node.nextSibling();
        4).读取根节点的最后一个子节点: 
            QDomNode lastnode = root.lastChild();  
5).匹配节点标记:
            node.toElement().tagName() == "book";
        6).匹配节点key为"id"的value值: 
            node.toElement().attribute("id") == "01";
        7).匹配节点的文本内容:

            titlenode.toElement().text() == "Qt";

8).修改author节点的text内容

	QDomNode oldnode = authornode.firstChild();
	authornode.firstChild().setNodeValue("new authorname"); //赋予新的内容
        QDomNode newnode = authornode.firstChild();   //值修改过后
        authornode.replaceChild(newnode,oldnode);        //调用节点的



6> 删除便签时,要删除相应的XML节点.
用到的主要函数为:root.removeChild(node); 
但在删除某个节点后要重写整个文件,因此在文件的打开方式中要加上QIODevice::Truncate,表示覆盖重写。


        QFile file(filepath);
        file.open(QIODevice::ReadOnly);
        file.close();
        //按照节点的key-value值比较来删除    
        QDomNodeList list = doc.elementsByTagName("book");//取出所有的book元素,放入list容器内
        for(int i=0; i<list.count(); i++)//循环比较
        {
            QDomElement e = list.at(i).toElement();


            if(e.attribute(tr("id")) == "01")//取book节点的value值与字符串"01"比较,如果相同
            {
                QDomElement root = doc.documentElement();  //取出根节点
                root.removeChild(list.at(i));  //从根节点上删除该节点
                qDebug() << "remove ok !";


                if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))//删除时要覆盖重写
                    return ;
                QTextStream out(&file);
                doc.save(out,4);
                file.close();             
            }
        }
        //按照节点的文本内容来删除
        QDomNodeList list = doc.elementsByTagName("book");//取出所有的book元素,放入list容器内
        for(int i=0; i<list.count(); i++)//循环比较
        {
            QDomElement booknode = list.at(i).toElement();
            QDomElement titlenode = booknode.firstChildElement();


            if(titlenode.toElement().text() == "Qt") //当节点文本内容一致时
            {
                QDomElement root = doc.documentElement();  //取出根节点
                root.removeChild(list.at(i));  //从根节点上删除该book节点
                qDebug() << "remove ok !";


                if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))//删除时要覆盖重写
                    return ;
                QTextStream out(&file);
                doc.save(out,4);
                file.close();             
            }
        }


4. SAX方式
1> 优点:它提供了比DOM更简单的接口,并且它不需要将整个XML文档一次性读入内存,这样便可以用来读取较大的文件。


2> 缺点:只能读取并显示整个XML文档


3> 流程:在Qt的QtXml模块中提供了一个QXmlSimpleReader的类,它便是基于SAX的XML解析器。
这个解析器是基于事件的,但这些事件由它们自身进行关联,我们并不需要进行设置。
我们只需知道,当解析器解析一个XML的元素时,就会执行相应的事件,
我们只要重写这些事件处理函数,就能让它按照我们的想法进行解析。
比如要解析下面的元素:
<title>Qt</title>
解析器会依次调用如下事件处理函数:startElement(),characters(),endElement()。
我们可以在startElement()中获得元素名(如“title”)和属性,
在characters()中获得元素中的文本(如“Qt”),
在endElement()中进行一些结束读取该元素时想要进行的操作。
而所有的这些事件处理函数我们都可以通过继承QXmlDefaultHandler类来重写。


5. 流方法
 一种快速的基于流的方式访问良格式 XML 文档,特别适合于实现一次解析器(所谓“一次解析器”,可以理解
成我们只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会有反复的情况,
也就是不会读完第一个标签,然后读第二个,读完第二个又返回去读第一个,这是不允许的);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值